phoria2 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -6
- package/dist/bloom.js +4 -4
- package/dist/bloom.js.map +1 -1
- package/dist/charts.js +436 -436
- package/dist/charts.js.map +1 -1
- package/dist/core.js +1240 -862
- package/dist/core.js.map +1 -1
- package/dist/debug.js +297 -0
- package/dist/debug.js.map +1 -0
- package/dist/edit.js +40 -40
- package/dist/edit.js.map +1 -1
- package/dist/explain.js +32 -13
- package/dist/explain.js.map +1 -1
- package/dist/gltf.js +128 -128
- package/dist/gltf.js.map +1 -1
- package/dist/keyboard.js +19 -19
- package/dist/keyboard.js.map +1 -1
- package/dist/motion.js +35 -35
- package/dist/motion.js.map +1 -1
- package/dist/particles.js +36 -36
- package/dist/particles.js.map +1 -1
- package/dist/passes.js +116 -104
- package/dist/passes.js.map +1 -1
- package/dist/phoria2.js +1 -1
- package/dist/picking.js +90 -71
- package/dist/picking.js.map +1 -1
- package/dist/snapshot.js +1 -1
- package/dist/tooltip.js +1 -1
- package/dist/types/View.d.ts +16 -0
- package/dist/types/debug.d.ts +74 -0
- package/dist/types/explain.d.ts +4 -0
- package/dist/types/frame.d.ts +5 -0
- package/dist/types/material/Material.d.ts +52 -0
- package/dist/types/watch.d.ts +8 -1
- package/dist/types/webgl/hooks.d.ts +48 -0
- package/dist/types/webgl/passes.d.ts +4 -0
- package/dist/types/webgl/programs.d.ts +15 -5
- package/dist/types/webgl/shaders.d.ts +36 -5
- package/llms-full.txt +227 -0
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/schema/scene.schema.json +27 -0
- package/src/View.js +105 -7
- package/src/debug.js +283 -0
- package/src/explain.js +19 -0
- package/src/frame.js +7 -2
- package/src/material/Material.js +121 -2
- package/src/scene/drawables.js +21 -4
- package/src/watch.js +18 -2
- package/src/webgl/WebGLRenderer.js +19 -2
- package/src/webgl/hooks.js +121 -0
- package/src/webgl/passes.js +17 -2
- package/src/webgl/picking.js +23 -2
- package/src/webgl/programs.js +20 -9
- package/src/webgl/resources.js +1 -1
- package/src/webgl/shaders.js +443 -35
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","names":["create","identity","invert","multiply","cross","distance","normalize","vec3.add","vec3.subtract","vec3.scale","vec3.normalize","vec3.negate","vec3.lerp","vec3.cross","vec3.dot","vec3.length","vec3.distance","vec3.transformMat4","vec3.transformQuat","mat4.identity","mat4.multiply","mat4.invert","mat4.fromRotationTranslationScale","mat4.lookAt","mat4.create","mat4.ortho","mat4.perspective","mat4.multiply","OPTIONS","OPTIONS","DEFAULTS","HINTS","OPTIONS","HINTS","UP","quat.fromEulerXYZ","quat.fromMat3","mat3.fromMat4","quat.normalize","quat.invert","instanceLabels","ids","nextId","OPTIONS","HINTS","quat.normalize","quat.fromMat3","mat3.fromMat4","mat4.perspective","mat4.ortho","instanceWorld","mat4.invert","mat4.multiply","mat3.normalFromMat4","outline","OPTIONS","HINTS","mat4.multiply","mat3.normalFromMat4","mat4.determinant","HINTS","TAU","resolve","size","count","types","generators","__defProp","__exportAll","target","name","all","no_symbols","EPSILON","create$1","identity$1","out","invert$1","a00","a","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b06","b07","b08","b09","b10","b11","det","determinant","b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","multiply$1","c","b","perspective","f","fovy","aspect","far","nf","near","lookAt","ex","eye","ey","ez","center","z0","z1","z2","len","x0","up","x1","x2","y0","y1","y2","fromRotationTranslationScale","x","q","y","z","w","xx","xy","xz","yy","yz","zz","wx","wy","wz","sx","s","sy","sz","v","ortho","lr","left","right","bt","bottom","top","targetTo","add","subtract","scale","dot","cross$1","ax","ay","az","bx","by","bz","length","distance$1","normalize$1","transformMat4","m","transformQuat","qx","qy","qz","qw","uvx","uvy","uvz","uuvx","uuvy","uuvz","w2","lerp","t","negate","PhoriaError","fail","owner","message","distance","d","i","j","cost","suggest","lower","list","candidates","prefixed","best","bestScore","score","didYouMean","checkOptions","options","keys","known","describe","key","hints","checkNumber","checkRange","n","above","min","max","checkOneOf","allowed","hint","warned","warnOnce","seen","resolveOptions","o","fromNumber","checkLength","value","fallback","zero","checkCount","Vec3","toArray","epsilon","Mat4","quaternion","position","Box3","p","positions","box","SHADOW_MAP_SIZE","fitShadow","boxes","casters","normalized","direction","view","corners","px","py","pz","across","area","receivers","margin","depthMargin","steps","h","tx","size","ty","dz","projection","viewProjection","SPOT_ATLAS_SIZE","fitSpotShadow","at","depths","caster","range","fov","angle","POINT_SHADOW_SIZE","CUBE_FACES","fitPointShadow","dx","dy","CSS_COLORS","hex","pair","toLinear","toSRGB","clamp01","NUMBER","FUNC","HELP","PARSED","PARSED_MAX","Color","input","#setHex","#setString","arr","g","r","#parse","named","fn","aUnit","bUnit","cUnit","channel","unit","sat","light","hue","CLIP_OPTIONS","CLIP_HINTS","Clip","json","worldPlane","clip","node","l","nx","ny","nz","c0","c1","c2","ox","oy","oz","clipOwner","Euler","#x","#y","#z","e","m11","m12","m13","m22","m23","m32","m33","setAxisAngle","rad","axis","multiply","aw","bw","normalize","invert","inv","slerp","cosom","s0","s1","omega","sinom","fromMat3","trace","root","k","fromEulerXYZ","c3","s2","s3","Quat","OPTIONS$5","POINT_ARRAYS","Geometry","toFloat32","#normals","#autoNormals","#bounds","#changed","flat","#unweld","normals","triangles","#index","abx","aby","abz","acx","acy","acz","#onDispose","idx","expand","src","values","count","OPTIONS$4","DEFAULTS$1","HINTS$5","CHANGES_KEPT","Texture","#colorSpace","#colorSpaceSet","isVideo","VIDEO","loaded","#load","#image","#follow","video","frame","last","running","tick","start","changed","region","width","height","#changes","first","version","regions","current","url","response","parseHDR","img","image","resolve","reject","loadTexture","MAPS","LINEAR_MAPS","FLAGS","NUMBERS","COLORS","DEFAULTS","OPTIONS$3","HINTS$4","Material","#colors","bool","#maps","slot","#transparent","parts","copy","desc","keepTextures","resolveGeometry","type","resolveMaterial","identity","normalFromMat4","fromMat4","NODE_OPTIONS","NODE_HINTS","NO_HANDLERS","UP$1","tmpMat","tmpMat3","Node","#position","#scale","#rotation","#quaternion","Class","#setHighlight","#clip","#setOutline","child","#highlight","#outline","#parent","#children","more","nodes","toNode","#detach","found","predicate","#addUpdate","#handlers","event","#listeners","set","own","dt","offset","toward","dir","world","parentRot","normalizedRotation","#updateAncestors","#updateSelf","camera","deep","setPoint","inParentSpace","parent","Group","LABEL_PLACES","PLACEMENT_OPTIONS","LABEL_HINTS","INSTANCE_LABEL_HINTS","placement","minScale","instanceLabels$1","one","byRow","style","DRAWABLE_OPTIONS","DRAWABLE_HINTS","Drawable","#geometry","#material","index","Mesh","INSTANCE_OPTIONS","scratch","SCRATCH_COLOR","scratchMatrix","hiddenInstance","InstancedMesh","inst","#checkIndex","#setColor","color","local","cx","cy","cz","im","hx","hy","hz","Points","ARROWS","Lines","Label","LIGHT_LIMITS","collect","planes","frustumPlanes","scene","punctual","directional","capped","visit","outline","item","drawItem","blended","solids","instanceLabels","project","addLight","kind","items","capOf","sun","spots","points","fit","sphereInFrustum","receiving","bounds","instances","geometry","worldMatrix","cuts","off","ids$1","nextId$1","instanceLabelSet","labels","layer","yScale","id","instanced","data","row","text","toScreen","ndc","depth","rows","r0","r1","r2","r3","radius","NullRenderer","GAP","EDGE","CELL","NEW_OVERLAP","KEEP_OVERLAP","placeBox","edge","viewWidth","place","stackColumns","side","column","groups","group","gap","wants","shift","total","alignColumns","widest","leaderEnd","rule","layoutLabels","order","states","grid","cells","shared","blocked","other","SVG","DIM_OPACITY","LabelLayer","canvas","pointer","#ensureRoot","stats","#elements","overlays","#overlays","#root","#mount","rect","#place","active","label","#entry","entry","#leave","hidden","state","interactive","el","minWidth","textAlign","#leader","now","cs","end","#ensureLines","opacity","line","#lines","svg","#over","#byElement","className","#listen","entryOf","OPTIONS$2","HINTS$3","LIMIT","MAX_FLING","checkSettings","OrbitControl","element","down","#down","move","#move","#up","wheel","#wheel","menu","click","#dragged","#pointerHandlers","#removePointer","#removeListeners","pitch","#orthographic","yaw","dYaw","dPitch","cam","factor","before","#halfHeight","worldPerPixel","#pointers","#velocity","keep","still","#pinchDistance","#pressed","#lastMove","#spread","#panning","spread","elapsed","cap","UP","tmp","tmp3","aimAt","CAMERA_OPTIONS","CAMERA_HINTS","Camera","#target","PerspectiveCamera","OrthographicCamera","DIRECTIONS","CAMERA_PRESETS","ALIASES","cameraPreset","presetDirection","alias","LOW","fitPoints","padding","wide","ahead","axes","lo","hi","mid","centerOf","half","tanV","tanH","u0","u1","v0","v1","u","du","dv","framingScale","designed","ratio","EASES","edge1","edge2","pvec","tvec","qvec","Ray","origin","along","d2","t0","t1","normal","point","cullBack","closest","dd","denom","LEAF","cache","bvhOf","hit","bvh","build","corner","tri","maxNodes","used","grow","alloc","stack","cx0","cy0","cz0","cx1","cy1","cz1","partition","pivot","walk","ix","iy","iz","enter","worth","test","inverse","instanceWorld$1","localPlane","cutBy","Raycaster","hits","targets","#visit","cut","#mesh","skip","skipInstance","i0","i1","#points","mesh","bestT","bestFace","i2","normalMatrix","P","uv","datum","instance","w0","limit","distanceSq","instanceWorld","outline$1","inside","into","yi","yj","pickArea","shape","within","face","pos","centre","ids","nextId","idOf","ChangeWatch","#count","#strings","#camera","#scene","#previousCount","#previousStrings","#values","#previous","grown","previous","#push","#pushAll","bg","#texture","env","fog","#node","shown","#drawable","#label","#light","texture","FOG_OPTIONS","FOG_HINTS","Fog","linear","Scene","#setBackground","#setEnvironment","#fog","#background","#environment","runHandlers","waits","ran","children","LIGHT_OPTIONS","LIGHT_HINTS","Light","#color","AmbientLight","HemisphereLight","rest","sky","ground","#ground","AimedLight","#direction","DirectionalLight","#setShadowBounds","#shadowBounds","PointLight","rangeOf","SpotLight","ATTRIBUTES","CLIP","FOG","MAP_SAMPLERS","SAMPLING","CLIP_ONLY_FRAGMENT","COMMON","EQUIRECT","FULLSCREEN_VERTEX","TONE_MAP","MESH_VERTEX","MESH_FRAGMENT","POINTS_VERTEX","POINTS_FRAGMENT","LINES_VERTEX","LINES_FRAGMENT","SOURCES","shaderSource","header","defines","vs","fs","Programs","gl","#parallel","#cache","#start","sources","#finish","#empty","shader","source","program","shaders","numbered","setters","info","loc","sampler","setterFor","UPLOAD_UNIT","MOST_REGIONS","GRID","layoutOf","withNormals","withTangents","tangentsOf","e1x","e1y","e1z","e2x","e2y","e2z","du1","dv1","du2","dv2","tz","UV_MATRIX","uvMatrix","LINE_CORNERS","SPRITE_LAYOUT","SPRITE_STRIDE","Resources","#aniso","ext","#mark","#triangles","same","layout","#refill","#free","#watch","vao","buffers","attribute","buffer","location","divisor","attributes","matrixBuffer","colorBuffer","indexType","elements","segments","ends","colors","interleavedPair","second","chains","#cornerBuffer","#whiteTexture","#textures","#freeTexture","float","internal","sizeOf","byCell","wrap","nearest","aniso","#anisotropic","users","#usedBy","#sprites","sorting","modelView","backToFront","sizes","opacities","angles","#white","#corners","GLContext","isShared","released","lost","restored","user","needed","#passesLoading","Passes","#watchingCompiles","check","#pickerLoading","Picker","#bloomLoading","Bloom","lose","OPTIONS$1","BLOOM","BLOOM_OPTIONS","BLOOM_HINTS","HINTS$2","bloomSettings","settings","TONE_MAPPING","NO_SHADOWS","MAP_DEFINES","MAP_SLOTS","MAP_UNIFORMS","CLIP_MASK","CAP_SQUARE","CAP_NODE","WebGLRenderer","#bloom","#gpu","#copy","pixelRatio","gpu","#wait","wait","passes","#shadows","bloom","#gatherLights","#draw","#cap","picker","ambient","dirDirection","dirColor","shadowTile","cone","dirCount","punctualCount","pointShadowIndex","addColor","#lightDefines","#studio","#lights","mode","shadows","material","#defines","shadow","programs","hl","ior","sc","si","maps","bound","transparent","arrows","round","#modelView","#normalMatrix","masks","#capItem","#capMaterials","hasColors","define","hasUvs2","OPTIONS","FRAMING_OPTIONS","HINTS$1","EVENT_HINTS","HIGHLIGHT_AMOUNT","FOCUS_COLOR","OWN_CONTEXTS","GPU_PICKING","ownContexts","View","resolveCanvas","#ownCanvas","#autoFrame","#autoFrameFrom","cameraPlace","context","#ownContext","#pickPending","#setMotion","#pixelRatio","#explicitPixelRatio","orbit","#orbitPointer","#loadKeyboard","#labels","labelHandlers","#labelPointer","#keep","#designed","#schedule","old","#flight","#height","#width","#applied","#motion","#systemReduced","#description","#keyboard","#gaveRole","#hovered","#onFrame","#running","#lastTime","#dirty","#updateControls","#render","#fly","waiting","samePlace","#addAutoLights","#highlightFor","#occlude","#labelStats","#tooltip","#loadTooltip","#pointer","#keyFocus","#needsHover","cw","ch","#keepFraming","towards","duration","from","placeOf","#fit","setPlace","method","#drawnPoints","d0","d1","way","turnBetween","setTarget","drawnPoints","#gpuFrame","#exact","work","raycaster","indexed","#viewProjection","content","#tooltipContent","#tooltipClass","#tooltipLoading","#disposed","Tooltip","#tooltipFor","Keyboard","handlersAbove","snapshot","notes","drawn","onScreen","explain","#rafId","#cleanup","#onScreen","#tick","#updateHover","#setHovered","#keyAt","#labelHover","#dragging","#hoverBusy","request","nearestAbove","#clickable","was","whole","halfHeight","testing","press","#press","#drag","#moveDrag","leave","#endDrag","pressedAt","drag","resize","motion","follow","visible","plane","#noted","hemi","#autoSky","#autoSun","FIT_DETAIL","cos","triangulate","ring","placed","holes","hole","maxX","bridge","M","edges","bestD","crosses","around","cross","d3","d4","isEar","convex","generators_exports","GENERATOR_OPTIONS","cylinder","extrude","icosphere","lathe","sphere","torus","TAU$1","SEGMENT_HINT","Builder","BOX_FACES","rings","pole","sinT","cosT","phi","radiusTop","caps","axisOf","slope","tube","tubeSegments","theta","ct","st","detail","dirs","faces","level","midpoints","next","ab","bc","ca","pairs","spans","smoothed","nr","sin","withoutRepeats","front","cutouts","tris","lengths","perimeter","na","nb","CREASE","weld","remap","indices","use","divisions","stride","cols","pinchBottom","pinchTop","to","map","TURNS","kept","TAU","OUTLINE_OPTIONS","HINTS","circle","polygon","sides","arc","gear","teeth","step","OWNER","fromPolygons","polygons","xyz","pt","uvs","vertices","withUvs","pu","CURVE_OPTIONS","CURVE_HINTS","LINE_OPTIONS","LINE_HINTS","TUBE_OPTIONS","TUBE_HINTS","ELLIPSE_OPTIONS","SAMPLES","Curve","#closed","#tension","#spans","#lengths","prev","#raw","#toRaw","#segments","piece","dash","tangent","binormal","span","pts","get","p0","p1","p2","p3","f2","f3","h1","h2","h3","h4","chord","t2","m1","m2","curve","ellipse","ru","rv","tilt","turn","types$1","registerType","registeredTypes","GEOMETRY_TYPES","types","typeMap","THREE_TYPES","SUBPATH_TYPES","GEOMETRY_ALIASES","notANode","create","description","three","misplaced","createGeometry","make"],"sources":["../src/math/mat4.js","../src/math/vec3.js","../src/validate.js","../src/value/Vec3.js","../src/value/Mat4.js","../src/value/Box3.js","../src/shadow.js","../src/value/cssColors.js","../src/value/Color.js","../src/clip.js","../src/value/Euler.js","../src/math/quat.js","../src/value/Quat.js","../src/geometry/Geometry.js","../src/material/Texture.js","../src/material/Material.js","../src/resolve.js","../src/math/mat3.js","../src/scene/Node.js","../src/scene/drawables.js","../src/frame.js","../src/labelLayout.js","../src/labels.js","../src/OrbitControl.js","../src/scene/cameras.js","../src/presets.js","../src/ease.js","../src/value/Ray.js","../src/geometry/bvh.js","../src/Raycaster.js","../src/area.js","../src/watch.js","../src/fog.js","../src/scene/Scene.js","../src/scene/lights.js","../src/webgl/programs.js","../src/webgl/resources.js","../src/webgl/context.js","../src/webgl/WebGLRenderer.js","../src/View.js","../src/geometry/triangulate.js","../src/geometry/generators.js","../src/geometry/outline.js","../src/geometry/fromPolygons.js","../src/geometry/Curve.js","../src/registry.js","../src/describe.js"],"sourcesContent":["// 4x4 matrices as column-major Float32Array(16), the layout WebGL expects. Signatures follow\n// gl-matrix: results are written to `out`, which is also returned. Operations such as\n// translate(out, a, v) post-multiply - out = a * T(v) - so chained calls apply in object space.\n\n/** @typedef {Float32Array | number[]} Mat4Like */\n/** @typedef {Float32Array | number[]} Vec3Like */\n\nconst EPSILON = 0.000001\n\n/** @returns {Float32Array} identity */\nexport function create() {\n return identity(new Float32Array(16))\n}\n\n/** @template {Mat4Like} T @param {T} out @returns {T} */\nexport function identity(out) {\n out.fill(0)\n out[0] = out[5] = out[10] = out[15] = 1\n return out\n}\n\n/** @template {Mat4Like} T @param {T} out @param {Mat4Like} a @returns {T} */\nexport function transpose(out, a) {\n if (out === a) {\n const a01 = a[1], a02 = a[2], a03 = a[3], a12 = a[6], a13 = a[7], a23 = a[11]\n out[1] = a[4]; out[2] = a[8]; out[3] = a[12]\n out[4] = a01; out[6] = a[9]; out[7] = a[13]\n out[8] = a02; out[9] = a12; out[11] = a[14]\n out[12] = a03; out[13] = a13; out[14] = a23\n return out\n }\n for (let c = 0; c < 4; c++) {\n for (let r = 0; r < 4; r++) out[c * 4 + r] = a[r * 4 + c]\n }\n return out\n}\n\n/** @template {Mat4Like} T @param {T} out @param {Mat4Like} a @returns {T | null} null if not invertible */\nexport function invert(out, a) {\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]\n\n const b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10\n const b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11\n const b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12\n const b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30\n const b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31\n const b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32\n\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06\n if (!det) return null\n det = 1 / det\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det\n return out\n}\n\n/** @param {Mat4Like} a @returns {number} */\nexport function determinant(a) {\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]\n const b0 = a00 * a11 - a01 * a10, b1 = a00 * a12 - a02 * a10\n const b2 = a01 * a12 - a02 * a11, b3 = a20 * a31 - a21 * a30\n const b4 = a20 * a32 - a22 * a30, b5 = a21 * a32 - a22 * a31\n const b6 = a00 * b5 - a01 * b4 + a02 * b3\n const b7 = a10 * b5 - a11 * b4 + a12 * b3\n const b8 = a20 * b2 - a21 * b1 + a22 * b0\n const b9 = a30 * b2 - a31 * b1 + a32 * b0\n return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9\n}\n\n/** out = a * b @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {Mat4Like} b @returns {T} */\nexport function multiply(out, a, b) {\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]\n // one column of b at a time, so out may alias a or b\n for (let c = 0; c < 16; c += 4) {\n const b0 = b[c], b1 = b[c + 1], b2 = b[c + 2], b3 = b[c + 3]\n out[c] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30\n out[c + 1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31\n out[c + 2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32\n out[c + 3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33\n }\n return out\n}\n\nexport const mul = multiply\n\n/** out = a * T(v) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {Vec3Like} v @returns {T} */\nexport function translate(out, a, v) {\n const x = v[0], y = v[1], z = v[2]\n if (out !== a) for (let i = 0; i < 12; i++) out[i] = a[i]\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]\n return out\n}\n\n/** out = a * S(v) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {Vec3Like} v @returns {T} */\nexport function scale(out, a, v) {\n for (let i = 0; i < 4; i++) {\n out[i] = a[i] * v[0]\n out[i + 4] = a[i + 4] * v[1]\n out[i + 8] = a[i + 8] * v[2]\n out[i + 12] = a[i + 12]\n }\n return out\n}\n\n/** out = a * R(axis, rad); returns null for a zero-length axis @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {number} rad @param {Vec3Like} axis @returns {T | null} */\nexport function rotate(out, a, rad, axis) {\n let x = axis[0], y = axis[1], z = axis[2]\n let len = Math.hypot(x, y, z)\n if (len < EPSILON) return null\n len = 1 / len\n x *= len\n y *= len\n z *= len\n const s = Math.sin(rad), c = Math.cos(rad), t = 1 - c\n\n // rotation matrix\n const b00 = x * x * t + c, b01 = y * x * t + z * s, b02 = z * x * t - y * s\n const b10 = x * y * t - z * s, b11 = y * y * t + c, b12 = z * y * t + x * s\n const b20 = x * z * t + y * s, b21 = y * z * t - x * s, b22 = z * z * t + c\n\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n out[0] = a00 * b00 + a10 * b01 + a20 * b02\n out[1] = a01 * b00 + a11 * b01 + a21 * b02\n out[2] = a02 * b00 + a12 * b01 + a22 * b02\n out[3] = a03 * b00 + a13 * b01 + a23 * b02\n out[4] = a00 * b10 + a10 * b11 + a20 * b12\n out[5] = a01 * b10 + a11 * b11 + a21 * b12\n out[6] = a02 * b10 + a12 * b11 + a22 * b12\n out[7] = a03 * b10 + a13 * b11 + a23 * b12\n out[8] = a00 * b20 + a10 * b21 + a20 * b22\n out[9] = a01 * b20 + a11 * b21 + a21 * b22\n out[10] = a02 * b20 + a12 * b21 + a22 * b22\n out[11] = a03 * b20 + a13 * b21 + a23 * b22\n if (out !== a) for (let i = 12; i < 16; i++) out[i] = a[i]\n return out\n}\n\n// Rotating about a principal axis mixes two columns of `a`: col i and col j.\nfunction rotateColumns(out, a, rad, i, j, sign) {\n const s = Math.sin(rad) * sign, c = Math.cos(rad)\n if (out !== a) for (let k = 0; k < 16; k++) out[k] = a[k]\n for (let k = 0; k < 4; k++) {\n const ai = a[i + k], aj = a[j + k]\n out[i + k] = ai * c + aj * s\n out[j + k] = aj * c - ai * s\n }\n return out\n}\n\n/** out = a * Rx(rad) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {number} rad @returns {T} */\nexport const rotateX = (out, a, rad) => rotateColumns(out, a, rad, 4, 8, 1)\n/** out = a * Ry(rad) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {number} rad @returns {T} */\nexport const rotateY = (out, a, rad) => rotateColumns(out, a, rad, 0, 8, -1)\n/** out = a * Rz(rad) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {number} rad @returns {T} */\nexport const rotateZ = (out, a, rad) => rotateColumns(out, a, rad, 0, 4, 1)\n\n/** Rotation matrix from a quaternion [x, y, z, w]. @template {Mat4Like} T @param {T} out @param {Float32Array | number[]} q @returns {T} */\nexport function fromQuat(out, q) {\n const x = q[0], y = q[1], z = q[2], w = q[3]\n const x2 = x + x, y2 = y + y, z2 = z + z\n const xx = x * x2, yx = y * x2, yy = y * y2\n const zx = z * x2, zy = z * y2, zz = z * z2\n const wx = w * x2, wy = w * y2, wz = w * z2\n out[0] = 1 - yy - zz; out[1] = yx + wz; out[2] = zx - wy; out[3] = 0\n out[4] = yx - wz; out[5] = 1 - xx - zz; out[6] = zy + wx; out[7] = 0\n out[8] = zx + wy; out[9] = zy - wx; out[10] = 1 - xx - yy; out[11] = 0\n out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1\n return out\n}\n\n// Perspective projection with a -1..1 clip-space depth range (OpenGL/WebGL). `far` may be\n// Infinity. A negative fovy flips the image vertically.\n/** @template {Mat4Like} T @param {T} out @param {number} fovy radians @param {number} aspect @param {number} near @param {number} far @returns {T} */\nexport function perspective(out, fovy, aspect, near, far) {\n const f = 1 / Math.tan(fovy / 2)\n out.fill(0)\n out[0] = f / aspect\n out[5] = f\n out[11] = -1\n if (far != null && far !== Infinity) {\n const nf = 1 / (near - far)\n out[10] = (far + near) * nf\n out[14] = 2 * far * near * nf\n } else {\n out[10] = -1\n out[14] = -2 * near\n }\n return out\n}\n\n// View matrix for an eye looking at a centre point. Returns identity when eye and centre match.\n/** @template {Mat4Like} T @param {T} out @param {Vec3Like} eye @param {Vec3Like} center @param {Vec3Like} up @returns {T} */\nexport function lookAt(out, eye, center, up) {\n const ex = eye[0], ey = eye[1], ez = eye[2]\n if (Math.abs(ex - center[0]) < EPSILON && Math.abs(ey - center[1]) < EPSILON && Math.abs(ez - center[2]) < EPSILON) {\n return identity(out)\n }\n // z axis points from the centre back to the eye\n let z0 = ex - center[0], z1 = ey - center[1], z2 = ez - center[2]\n let len = 1 / Math.hypot(z0, z1, z2)\n z0 *= len; z1 *= len; z2 *= len\n\n let x0 = up[1] * z2 - up[2] * z1\n let x1 = up[2] * z0 - up[0] * z2\n let x2 = up[0] * z1 - up[1] * z0\n len = Math.hypot(x0, x1, x2)\n if (!len) {\n x0 = x1 = x2 = 0\n } else {\n len = 1 / len\n x0 *= len; x1 *= len; x2 *= len\n }\n\n let y0 = z1 * x2 - z2 * x1\n let y1 = z2 * x0 - z0 * x2\n let y2 = z0 * x1 - z1 * x0\n len = Math.hypot(y0, y1, y2)\n if (!len) {\n y0 = y1 = y2 = 0\n } else {\n len = 1 / len\n y0 *= len; y1 *= len; y2 *= len\n }\n\n out[0] = x0; out[1] = y0; out[2] = z0; out[3] = 0\n out[4] = x1; out[5] = y1; out[6] = z1; out[7] = 0\n out[8] = x2; out[9] = y2; out[10] = z2; out[11] = 0\n out[12] = -(x0 * ex + x1 * ey + x2 * ez)\n out[13] = -(y0 * ex + y1 * ey + y2 * ez)\n out[14] = -(z0 * ex + z1 * ey + z2 * ez)\n out[15] = 1\n return out\n}\n\n/** Compose translation, rotation and scale: T * R * S. @template {Mat4Like} T @param {T} out @param {Float32Array | number[]} q @param {Vec3Like} v @param {Vec3Like} s @returns {T} */\nexport function fromRotationTranslationScale(out, q, v, s) {\n const x = q[0], y = q[1], z = q[2], w = q[3]\n const x2 = x + x, y2 = y + y, z2 = z + z\n const xx = x * x2, xy = x * y2, xz = x * z2\n const yy = y * y2, yz = y * z2, zz = z * z2\n const wx = w * x2, wy = w * y2, wz = w * z2\n const sx = s[0], sy = s[1], sz = s[2]\n out[0] = (1 - (yy + zz)) * sx; out[1] = (xy + wz) * sx; out[2] = (xz - wy) * sx; out[3] = 0\n out[4] = (xy - wz) * sy; out[5] = (1 - (xx + zz)) * sy; out[6] = (yz + wx) * sy; out[7] = 0\n out[8] = (xz + wy) * sz; out[9] = (yz - wx) * sz; out[10] = (1 - (xx + yy)) * sz; out[11] = 0\n out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1\n return out\n}\n\n/** Orthographic projection with a -1..1 clip-space depth range. @template {Mat4Like} T @param {T} out @param {number} left @param {number} right @param {number} bottom @param {number} top @param {number} near @param {number} far @returns {T} */\nexport function ortho(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right), bt = 1 / (bottom - top), nf = 1 / (near - far)\n out.fill(0)\n out[0] = -2 * lr\n out[5] = -2 * bt\n out[10] = 2 * nf\n out[12] = (left + right) * lr\n out[13] = (top + bottom) * bt\n out[14] = (far + near) * nf\n out[15] = 1\n return out\n}\n\n// Model matrix placing an object at `eye` with its -Z axis pointing at `target` - the inverse of\n// a lookAt view matrix. Used to aim cameras, lights and nodes.\n/** @template {Mat4Like} T @param {T} out @param {Vec3Like} eye @param {Vec3Like} target @param {Vec3Like} up @returns {T} */\nexport function targetTo(out, eye, target, up) {\n const ex = eye[0], ey = eye[1], ez = eye[2]\n let z0 = ex - target[0], z1 = ey - target[1], z2 = ez - target[2]\n let len = z0 * z0 + z1 * z1 + z2 * z2\n if (len > 0) {\n len = 1 / Math.sqrt(len)\n z0 *= len; z1 *= len; z2 *= len\n }\n let x0 = up[1] * z2 - up[2] * z1, x1 = up[2] * z0 - up[0] * z2, x2 = up[0] * z1 - up[1] * z0\n len = x0 * x0 + x1 * x1 + x2 * x2\n if (len > 0) {\n len = 1 / Math.sqrt(len)\n x0 *= len; x1 *= len; x2 *= len\n }\n out[0] = x0; out[1] = x1; out[2] = x2; out[3] = 0\n out[4] = z1 * x2 - z2 * x1; out[5] = z2 * x0 - z0 * x2; out[6] = z0 * x1 - z1 * x0; out[7] = 0\n out[8] = z0; out[9] = z1; out[10] = z2; out[11] = 0\n out[12] = ex; out[13] = ey; out[14] = ez; out[15] = 1\n return out\n}\n","// 3D vectors as Float32Array(3). Signatures follow gl-matrix: results are written to `out`,\n// which is also returned. Functions only read and write the first three components, so a vec4\n// can be passed where a vec3 is expected (its w is left alone).\n\n/** @typedef {Float32Array | number[]} Vec3Like */\n\n/** @returns {Float32Array} */\nexport const create = () => new Float32Array(3)\n\n/** @param {number} x @param {number} y @param {number} z @returns {Float32Array} */\nexport function fromValues(x, y, z) {\n const out = new Float32Array(3)\n out[0] = x\n out[1] = y\n out[2] = z\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @returns {T} */\nexport function add(out, a, b) {\n out[0] = a[0] + b[0]\n out[1] = a[1] + b[1]\n out[2] = a[2] + b[2]\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @returns {T} */\nexport function subtract(out, a, b) {\n out[0] = a[0] - b[0]\n out[1] = a[1] - b[1]\n out[2] = a[2] - b[2]\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {number} s @returns {T} */\nexport function scale(out, a, s) {\n out[0] = a[0] * s\n out[1] = a[1] * s\n out[2] = a[2] * s\n return out\n}\n\n/** out = a + b * s @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @param {number} s @returns {T} */\nexport function scaleAndAdd(out, a, b, s) {\n out[0] = a[0] + b[0] * s\n out[1] = a[1] + b[1] * s\n out[2] = a[2] + b[2] * s\n return out\n}\n\n/** @param {Vec3Like} a @param {Vec3Like} b @returns {number} */\nexport const dot = (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @returns {T} */\nexport function cross(out, a, b) {\n const ax = a[0], ay = a[1], az = a[2]\n const bx = b[0], by = b[1], bz = b[2]\n out[0] = ay * bz - az * by\n out[1] = az * bx - ax * bz\n out[2] = ax * by - ay * bx\n return out\n}\n\n/** @param {Vec3Like} a @returns {number} */\nexport const length = (a) => Math.hypot(a[0], a[1], a[2])\n\n/** @param {Vec3Like} a @param {Vec3Like} b @returns {number} */\nexport const distance = (a, b) => Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2])\n\n// A zero vector normalises to zero rather than NaN.\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @returns {T} */\nexport function normalize(out, a) {\n const x = a[0], y = a[1], z = a[2]\n let len = x * x + y * y + z * z\n if (len > 0) len = 1 / Math.sqrt(len)\n out[0] = x * len\n out[1] = y * len\n out[2] = z * len\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Float32Array | number[]} m 3x3 column-major @returns {T} */\nexport function transformMat3(out, a, m) {\n const x = a[0], y = a[1], z = a[2]\n out[0] = x * m[0] + y * m[3] + z * m[6]\n out[1] = x * m[1] + y * m[4] + z * m[7]\n out[2] = x * m[2] + y * m[5] + z * m[8]\n return out\n}\n\n/** Transform a point by a 4x4, dividing by w. @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Float32Array | number[]} m @returns {T} */\nexport function transformMat4(out, a, m) {\n const x = a[0], y = a[1], z = a[2]\n const w = (m[3] * x + m[7] * y + m[11] * z + m[15]) || 1\n out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w\n out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w\n out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w\n return out\n}\n\n/** Rotate a vector by a quaternion. @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Float32Array | number[]} q @returns {T} */\nexport function transformQuat(out, a, q) {\n const qx = q[0], qy = q[1], qz = q[2], qw = q[3]\n const x = a[0], y = a[1], z = a[2]\n // v' = v + 2w(q x v) + 2(q x (q x v))\n let uvx = qy * z - qz * y, uvy = qz * x - qx * z, uvz = qx * y - qy * x\n let uuvx = qy * uvz - qz * uvy, uuvy = qz * uvx - qx * uvz, uuvz = qx * uvy - qy * uvx\n const w2 = qw * 2\n uvx *= w2; uvy *= w2; uvz *= w2\n uuvx *= 2; uuvy *= 2; uuvz *= 2\n out[0] = x + uvx + uuvx\n out[1] = y + uvy + uuvy\n out[2] = z + uvz + uuvz\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @param {number} t @returns {T} */\nexport function lerp(out, a, b, t) {\n out[0] = a[0] + t * (b[0] - a[0])\n out[1] = a[1] + t * (b[1] - a[1])\n out[2] = a[2] + t * (b[2] - a[2])\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @returns {T} */\nexport function negate(out, a) {\n out[0] = -a[0]\n out[1] = -a[1]\n out[2] = -a[2]\n return out\n}\n","// Validation helpers. Options and descriptions are checked once, when an object is created or a\n// property set - never per frame - and errors name the object, the problem and the fix.\n\n/** Error thrown for invalid phoria2 input. Its message always says what to do instead. */\nexport class PhoriaError extends Error {\n name = 'PhoriaError'\n}\n\n/**\n * Throw a PhoriaError: `${owner}: ${message}`.\n * @param {string} owner the object or function the input was for, e.g. 'Mesh' or 'box()'\n * @param {string} message\n * @returns {never}\n */\nexport function fail(owner, message) {\n throw new PhoriaError(`${owner}: ${message}`)\n}\n\n// Edit distance where swapping two neighbouring letters counts as one edit ('widht' -> 'width'),\n// for did-you-mean suggestions.\nfunction distance(a, b) {\n const d = Array.from({ length: a.length + 1 }, (_, i) => Array.from({ length: b.length + 1 }, (_, j) => (i ? (j ? 0 : i) : j)))\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1\n d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost)\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1)\n }\n }\n return d[a.length][b.length]\n}\n\n/**\n * The closest candidate to a mistyped name, or undefined if nothing is close.\n * @param {string} name\n * @param {Iterable<string>} candidates\n * @returns {string | undefined}\n */\nexport function suggest(name, candidates) {\n const lower = name.toLowerCase()\n // a list, since an iterator could only be read once\n const list = [...candidates]\n // an abbreviation that only one candidate starts with ('w' -> 'width')\n const prefixed = list.filter((c) => c.toLowerCase().startsWith(lower))\n if (prefixed.length === 1) return prefixed[0]\n let best, bestScore = Infinity\n for (const c of list) {\n const score = c.toLowerCase() === lower ? 0 : distance(lower, c.toLowerCase())\n if (score < bestScore) {\n best = c\n bestScore = score\n }\n }\n // allow roughly one edit per three characters\n return bestScore <= Math.max(1, Math.floor(name.length / 3)) ? best : undefined\n}\n\n/** \" - did you mean 'x'?\" or an empty string. @param {string} name @param {Iterable<string>} candidates */\nexport const didYouMean = (name, candidates) => {\n const s = suggest(name, candidates)\n return s ? ` - did you mean '${s}'?` : ''\n}\n\n/**\n * Check an options object only uses known keys. Known three.js-isms can map to a targeted hint.\n * @param {string} owner\n * @param {object} options\n * @param {Iterable<string>} known\n * @param {Record<string, string>} [hints] option name -> message for common mistakes\n * @param {string} [name] the option these are, when nested (e.g. 'framing'), so errors say which\n */\nexport function checkOptions(owner, options, known, hints = {}, name) {\n if (options == null) return\n const keys = new Set(known)\n if (typeof options !== 'object' || Array.isArray(options)) {\n const expected = name ? `'${name}' must be an options object - { ${[...keys].join(', ')} }` : 'expected an options object'\n fail(owner, `${expected}, got ${describe(options)}`)\n }\n for (const key of Object.keys(options)) {\n if (keys.has(key)) continue\n if (hints[key]) fail(owner, hints[key])\n fail(owner, `unknown option '${name ? `${name}.${key}` : key}'${didYouMean(key, keys)}`)\n }\n}\n\n/** A short description of a value for error messages. @param {unknown} v @returns {string} */\nexport function describe(v) {\n if (v === null) return 'null'\n if (Array.isArray(v)) return `an array of ${v.length}`\n if (typeof v === 'string') return `'${v}'`\n if (typeof v === 'object') return v.constructor?.name && v.constructor !== Object ? `a ${v.constructor.name}` : 'an object'\n return String(v)\n}\n\n/** @param {string} owner @param {string} name @param {unknown} v @returns {number} */\nexport function checkNumber(owner, name, v) {\n if (typeof v !== 'number' || Number.isNaN(v)) fail(owner, `'${name}' must be a number, got ${describe(v)}`)\n return v\n}\n\n/**\n * A number within limits: from min (or above it, with above: true) up to max.\n * @param {string} owner @param {string} name @param {unknown} v\n * @param {number} [min] @param {number} [max] @param {{ above?: boolean }} [options]\n * @returns {number}\n */\nexport function checkRange(owner, name, v, min = -Infinity, max = Infinity, { above = false } = {}) {\n const n = checkNumber(owner, name, v)\n if ((above ? !(n > min) : n < min) || n > max) {\n const limits = max === Infinity ? (above ? `above ${min}` : `${min} or more`) : above ? `above ${min} and up to ${max}` : `from ${min} to ${max}`\n fail(owner, `'${name}' must be ${limits}, got ${n}`)\n }\n return n\n}\n\n/**\n * @template {string} T\n * @param {string} owner @param {string} name @param {unknown} v @param {readonly T[]} allowed\n * @returns {T}\n */\nexport function checkOneOf(owner, name, v, allowed) {\n if (!allowed.includes(/** @type {T} */ (v))) {\n const hint = typeof v === 'string' ? didYouMean(v, allowed) : ''\n fail(owner, `'${name}' ${describe(v)} is not valid - expected ${allowed.map((a) => `'${a}'`).join(' | ')}${hint}`)\n }\n return /** @type {T} */ (v)\n}\n\nconst warned = new WeakMap()\n/**\n * console.warn once per object and message - for problems that would otherwise repeat every frame.\n * @param {object} target @param {string} message\n */\nexport function warnOnce(target, message) {\n let seen = warned.get(target)\n if (!seen) warned.set(target, seen = new Set())\n if (seen.has(message)) return\n seen.add(message)\n console.warn(`phoria2: ${message}`)\n}\n\n/**\n * A generator's options: an options object, or a number standing for its main size - checked against\n * the names it takes.\n * @param {string} owner @param {unknown} options @param {string[]} keys\n * @param {((n: number) => object) | null} fromNumber @param {Record<string, string>} [hints]\n * @returns {Record<string, any>}\n */\nexport function resolveOptions(owner, options, keys, fromNumber, hints) {\n const o = /** @type {object} */ (typeof options === 'number' && fromNumber ? fromNumber(options) : options)\n checkOptions(owner, o, keys, hints)\n return o ?? {}\n}\n\n/**\n * A length: a finite number above 0 (or 0 itself when `zero`), or the default when missing.\n * @param {string} owner @param {string} name @param {unknown} value @param {number} fallback\n * @param {boolean} [zero]\n * @returns {number}\n */\nexport function checkLength(owner, name, value, fallback, zero = false) {\n if (value === undefined) return fallback\n const n = checkNumber(owner, name, value)\n if (!Number.isFinite(n) || n < 0 || (n === 0 && !zero)) fail(owner, `'${name}' must be ${zero ? '0 or more' : 'more than 0'}, got ${n}`)\n return n\n}\n\n/**\n * A whole number - segments, sides, points - in [min, max], or the default when missing.\n * @param {string} owner @param {string} name @param {unknown} value @param {number} fallback\n * @param {number} [min] @param {number} [max]\n * @returns {number}\n */\nexport function checkCount(owner, name, value, fallback, min = 1, max = Infinity) {\n if (value === undefined) return fallback\n if (!Number.isInteger(value) || /** @type {number} */ (value) < min || /** @type {number} */ (value) > max) {\n fail(owner, `'${name}' must be a whole number ${max === Infinity ? `${min} or more` : `from ${min} to ${max}`}, got ${describe(value)}`)\n }\n return /** @type {number} */ (value)\n}\n","import * as vec3 from '../math/vec3.js'\nimport { checkNumber, describe, fail } from '../validate.js'\n\n/** @import { Vec3Input } from '../types.js' */\n\n/**\n * A 3D vector: a Float32Array(3) with x/y/z accessors and chainable methods, so it works both with\n * the vec3/mat4 functions and three.js-style code (`position.set(1, 2, 3)`, `position.x += 1`).\n */\nexport class Vec3 extends Float32Array {\n // slice(), map() etc. return plain Float32Arrays rather than calling this constructor\n static get [Symbol.species]() { return Float32Array }\n\n /** @param {number} [x] @param {number} [y] @param {number} [z] */\n constructor(x = 0, y = 0, z = 0) {\n super(3)\n this[0] = x\n this[1] = y\n this[2] = z\n }\n\n /** @internal\n * Convert input to a new Vec3: [x, y, z], { x, y, z }, a Vec3, or one number for all three.\n * @param {Vec3Input | number} v\n * @param {string} [owner] for error messages\n * @returns {Vec3}\n */\n static fromInput(v, owner = 'Vec3') {\n return new Vec3().copy(v, owner)\n }\n\n get x() { return this[0] }\n set x(v) { this[0] = v }\n get y() { return this[1] }\n set y(v) { this[1] = v }\n get z() { return this[2] }\n set z(v) { this[2] = v }\n\n /**\n * set(x, y, z) sets the components, three.js style. set(array, offset) keeps the typed array\n * behaviour.\n * @overload\n * @param {number} x @param {number} y @param {number} z\n * @returns {this}\n */\n /**\n * @overload\n * @param {ArrayLike<number>} array @param {number} [offset]\n * @returns {void}\n */\n /** @param {number | ArrayLike<number>} x @param {number} [y] @param {number} [z] */\n set(x, y, z) {\n if (typeof x !== 'number') {\n super.set(x, y ?? 0)\n return\n }\n this[0] = x\n this[1] = y ?? this[1]\n this[2] = z ?? this[2]\n return this\n }\n\n /** Set all three to one number - a uniform scale: `node.scale.setScalar(2)`. @param {number} s @returns {this} */\n setScalar(s) {\n this[0] = this[1] = this[2] = checkNumber('Vec3', 'setScalar', s)\n return this\n }\n\n /** Copy from any Vec3Input, or one number for all three. @param {Vec3Input | number} v @param {string} [owner] @returns {this} */\n copy(v, owner = 'Vec3') {\n if (typeof v === 'number') {\n this[0] = this[1] = this[2] = v\n } else if (v && (Array.isArray(v) || ArrayBuffer.isView(v)) && v.length >= 3) {\n this[0] = v[0]\n this[1] = v[1]\n this[2] = v[2]\n } else if (v && typeof v === 'object' && 'x' in v && 'y' in v && 'z' in v) {\n this[0] = v.x\n this[1] = v.y\n this[2] = v.z\n } else {\n fail(owner, `expected [x, y, z] or { x, y, z }, got ${describe(v)}`)\n }\n if (Number.isNaN(this[0] + this[1] + this[2])) fail(owner, `vector components must be numbers, got ${describe(v)}`)\n return this\n }\n\n /** @returns {Vec3} */\n clone() {\n return new Vec3(this[0], this[1], this[2])\n }\n\n /** @param {Vec3Input} v @returns {this} */\n add(v) {\n const o = toArray(v)\n return vec3.add(this, this, o)\n }\n\n /** @param {Vec3Input} v @returns {this} */\n sub(v) {\n return vec3.subtract(this, this, toArray(v))\n }\n\n /** @param {number} s @returns {this} */\n multiplyScalar(s) {\n return vec3.scale(this, this, s)\n }\n\n /** @returns {this} */\n normalize() {\n return vec3.normalize(this, this)\n }\n\n /** @returns {this} */\n negate() {\n return vec3.negate(this, this)\n }\n\n /** @param {Vec3Input} v @param {number} t @returns {this} */\n lerp(v, t) {\n return vec3.lerp(this, this, toArray(v), t)\n }\n\n /** @param {Vec3Input} v @returns {this} */\n cross(v) {\n return vec3.cross(this, this, toArray(v))\n }\n\n /** @param {Vec3Input} v @returns {number} */\n dot(v) {\n return vec3.dot(this, toArray(v))\n }\n\n // len(), not length(): a typed array already has a length property (3)\n /** @returns {number} */\n len() {\n return vec3.length(this)\n }\n\n /** @param {Vec3Input} v @returns {number} */\n distanceTo(v) {\n return vec3.distance(this, toArray(v))\n }\n\n /** Transform as a point (w = 1). @param {Float32Array | number[]} m 4x4 @returns {this} */\n applyMatrix4(m) {\n return vec3.transformMat4(this, this, m)\n }\n\n /** @param {Float32Array | number[]} q @returns {this} */\n applyQuaternion(q) {\n return vec3.transformQuat(this, this, q)\n }\n\n /** @param {Vec3Input} v @param {number} [epsilon] @returns {boolean} */\n equals(v, epsilon = 0) {\n const o = toArray(v)\n return Math.abs(this[0] - o[0]) <= epsilon && Math.abs(this[1] - o[1]) <= epsilon && Math.abs(this[2] - o[2]) <= epsilon\n }\n\n /** @returns {[number, number, number]} */\n toArray() {\n return [this[0], this[1], this[2]]\n }\n\n toJSON() {\n return this.toArray()\n }\n}\n\n/** @param {Vec3Input} v @returns {Float32Array | number[]} */\nfunction toArray(v) {\n return Array.isArray(v) || ArrayBuffer.isView(v) ? /** @type {Float32Array | number[]} */ (v) : Vec3.fromInput(v)\n}\n","import * as mat4 from '../math/mat4.js'\nimport { Vec3 } from './Vec3.js'\n\n/** A 4x4 matrix: a column-major Float32Array(16), identity by default, with a few chainable methods. */\nexport class Mat4 extends Float32Array {\n static get [Symbol.species]() { return Float32Array }\n\n constructor() {\n super(16)\n this[0] = this[5] = this[10] = this[15] = 1\n }\n\n /** @returns {this} */\n identity() {\n return mat4.identity(this)\n }\n\n /** @param {ArrayLike<number>} m @returns {this} */\n copy(m) {\n for (let i = 0; i < 16; i++) this[i] = m[i]\n return this\n }\n\n /** @returns {Mat4} */\n clone() {\n return new Mat4().copy(this)\n }\n\n /** this = this * m @param {ArrayLike<number>} m @returns {this} */\n multiply(m) {\n return mat4.multiply(this, this, /** @type {number[]} */ (m))\n }\n\n /** this = a * b @param {ArrayLike<number>} a @param {ArrayLike<number>} b @returns {this} */\n multiplyMatrices(a, b) {\n return mat4.multiply(this, /** @type {number[]} */ (a), /** @type {number[]} */ (b))\n }\n\n /** Invert in place; becomes all zeros if the matrix is singular. @returns {this} */\n invert() {\n if (!mat4.invert(this, this)) this.fill(0)\n return this\n }\n\n /** Compose from a translation, rotation and scale. @param {ArrayLike<number>} position @param {ArrayLike<number>} quaternion @param {ArrayLike<number>} scale @returns {this} */\n compose(position, quaternion, scale) {\n return mat4.fromRotationTranslationScale(this, /** @type {number[]} */ (quaternion), /** @type {number[]} */ (position), /** @type {number[]} */ (scale))\n }\n\n /** The translation part. @param {Vec3} [out] @returns {Vec3} */\n getPosition(out = new Vec3()) {\n return out.set(this[12], this[13], this[14])\n }\n\n /** The length of each basis vector. @param {Vec3} [out] @returns {Vec3} */\n getScale(out = new Vec3()) {\n return out.set(\n Math.hypot(this[0], this[1], this[2]),\n Math.hypot(this[4], this[5], this[6]),\n Math.hypot(this[8], this[9], this[10]))\n }\n\n /** @returns {number[]} */\n toArray() {\n return Array.from(this)\n }\n}\n","import { Vec3 } from './Vec3.js'\n\n/** An axis aligned bounding box. Empty (min > max) until a point is added. */\nexport class Box3 {\n min = new Vec3(Infinity, Infinity, Infinity)\n max = new Vec3(-Infinity, -Infinity, -Infinity)\n\n /** @param {ArrayLike<number>} [min] @param {ArrayLike<number>} [max] */\n constructor(min, max) {\n if (min) this.min.set(min[0], min[1], min[2])\n if (max) this.max.set(max[0], max[1], max[2])\n }\n\n /** @returns {this} */\n makeEmpty() {\n this.min.set(Infinity, Infinity, Infinity)\n this.max.set(-Infinity, -Infinity, -Infinity)\n return this\n }\n\n /** @returns {boolean} */\n isEmpty() {\n return this.max[0] < this.min[0] || this.max[1] < this.min[1] || this.max[2] < this.min[2]\n }\n\n /** @param {number} x @param {number} y @param {number} z @returns {this} */\n expandByXYZ(x, y, z) {\n const { min, max } = this\n if (x < min[0]) min[0] = x\n if (y < min[1]) min[1] = y\n if (z < min[2]) min[2] = z\n if (x > max[0]) max[0] = x\n if (y > max[1]) max[1] = y\n if (z > max[2]) max[2] = z\n return this\n }\n\n /** @param {ArrayLike<number>} p @returns {this} */\n expandByPoint(p) {\n return this.expandByXYZ(p[0], p[1], p[2])\n }\n\n /** Grow to contain flat xyz positions. @param {ArrayLike<number>} positions @returns {this} */\n expandByPositions(positions) {\n for (let i = 0; i < positions.length; i += 3) this.expandByXYZ(positions[i], positions[i + 1], positions[i + 2])\n return this\n }\n\n /** @param {Box3} box @returns {this} */\n union(box) {\n if (box.isEmpty()) return this\n this.expandByPoint(box.min)\n return this.expandByPoint(box.max)\n }\n\n /** Transform by a 4x4, keeping it axis aligned (bounds of the 8 transformed corners). @param {ArrayLike<number>} m @returns {this} */\n applyMatrix4(m) {\n if (this.isEmpty()) return this\n const [x0, y0, z0] = this.min, [x1, y1, z1] = this.max\n this.makeEmpty()\n for (const x of [x0, x1]) {\n for (const y of [y0, y1]) {\n for (const z of [z0, z1]) {\n this.expandByXYZ(\n m[0] * x + m[4] * y + m[8] * z + m[12],\n m[1] * x + m[5] * y + m[9] * z + m[13],\n m[2] * x + m[6] * y + m[10] * z + m[14])\n }\n }\n }\n return this\n }\n\n /** @param {Vec3} [out] @returns {Vec3} */\n getCenter(out = new Vec3()) {\n if (this.isEmpty()) return out.set(0, 0, 0)\n return out.set((this.min[0] + this.max[0]) / 2, (this.min[1] + this.max[1]) / 2, (this.min[2] + this.max[2]) / 2)\n }\n\n /** @param {Vec3} [out] @returns {Vec3} */\n getSize(out = new Vec3()) {\n if (this.isEmpty()) return out.set(0, 0, 0)\n return out.set(this.max[0] - this.min[0], this.max[1] - this.min[1], this.max[2] - this.min[2])\n }\n\n /** Radius of the sphere around getCenter() that contains the box. @returns {number} */\n getRadius() {\n return this.isEmpty() ? 0 : this.getSize().len() / 2\n }\n\n /** @param {ArrayLike<number>} p @returns {boolean} */\n containsPoint(p) {\n return p[0] >= this.min[0] && p[0] <= this.max[0] &&\n p[1] >= this.min[1] && p[1] <= this.max[1] &&\n p[2] >= this.min[2] && p[2] <= this.max[2]\n }\n\n /** @returns {Box3} */\n clone() {\n return new Box3(this.min, this.max)\n }\n\n /** @param {Box3} box @returns {this} */\n copy(box) {\n this.min.set(box.min[0], box.min[1], box.min[2])\n this.max.set(box.max[0], box.max[1], box.max[2])\n return this\n }\n}\n","// Where a directional light's shadow map looks: fitted every frame to what casts shadows, so there\n// is no shadow camera to configure. In the light's view a shadow only travels along the depth,\n// so the casters' extent across the view is all the map has to cover; the depth runs on to the\n// furthest receiver.\nimport * as mat4 from './math/mat4.js'\nimport { Mat4 } from './value/Mat4.js'\n\n/** @import { Box3 } from './value/Box3.js' */\n\n/** Shadow map size in texels. */\nexport const SHADOW_MAP_SIZE = 2048\n\n/**\n * @typedef {object} ShadowFit\n * @property {Mat4} viewProjection world to the light's clip space\n * @property {number} texelSize world units per shadow map texel\n */\n\n/**\n * Fit a directional light's shadow view to the world bounds of the casters (and the depth of the\n * receivers). Null when nothing casts.\n * @param {ArrayLike<number>} direction the way the light travels\n * @param {Box3[]} casters world bounds\n * @param {Box3[]} receivers world bounds\n * @param {number} [size] map size in texels\n * @param {Box3 | null} [area] the light's shadowBounds: the map covers this across, whatever casts\n * @returns {ShadowFit | null}\n */\nexport function fitShadow(direction, casters, receivers, size = SHADOW_MAP_SIZE, area = null) {\n const boxes = casters.filter((b) => !b.isEmpty())\n if (!boxes.length) return null\n const d = normalized(direction)\n // look along the light from the origin; only the orientation matters, the box comes next\n const up = Math.abs(d[1]) > 0.99 ? [0, 0, 1] : [0, 1, 0]\n const view = mat4.lookAt(mat4.create(), [0, 0, 0], d, up)\n\n let x0 = Infinity, x1 = -Infinity, y0 = Infinity, y1 = -Infinity, z0 = Infinity, z1 = -Infinity\n const corners = (/** @type {Box3} */ b, /** @type {boolean} */ across) => {\n for (let i = 0; i < 8; i++) {\n const px = i & 1 ? b.max[0] : b.min[0], py = i & 2 ? b.max[1] : b.min[1], pz = i & 4 ? b.max[2] : b.min[2]\n const x = view[0] * px + view[4] * py + view[8] * pz\n const y = view[1] * px + view[5] * py + view[9] * pz\n const z = view[2] * px + view[6] * py + view[10] * pz\n if (across) {\n if (x < x0) x0 = x\n if (x > x1) x1 = x\n if (y < y0) y0 = y\n if (y > y1) y1 = y\n }\n if (z < z0) z0 = z\n if (z > z1) z1 = z\n }\n }\n // across the light's view: the area it was given, or else the casters; in depth, everything that\n // casts - so a caster outside the area, between it and the light, still shadows it\n if (area) corners(area, true)\n for (const b of boxes) corners(b, !area)\n // receivers only stretch the depth (view z is negative in front, so the far end is the minimum)\n for (const b of receivers) if (!b.isEmpty()) corners(b, false)\n\n // a small margin, so the soft edge of the outermost caster's shadow isn't clipped\n const margin = Math.max(x1 - x0, y1 - y0, 1e-3) * 0.02\n x0 -= margin; x1 += margin; y0 -= margin; y1 += margin\n const depthMargin = Math.max(z1 - z0, 1e-3) * 0.01\n z0 -= depthMargin; z1 += depthMargin\n\n // steady while things move: the map grows and shrinks in small steps rather than with every change\n // in the casters' extent, and its edges sit on the texel grid, so a shadow that isn't moving falls\n // on the same texels every frame, instead of shimmering as the fit slides about under it\n const w = steps(x1 - x0), h = steps(y1 - y0)\n const tx = w / size, ty = h / size\n x0 = Math.floor((x0 + x1 - w) / 2 / tx) * tx\n y0 = Math.floor((y0 + y1 - h) / 2 / ty) * ty\n // the depth range too, which sets what each stored depth means\n const dz = steps(z1 - z0) / 64\n z0 = Math.floor(z0 / dz) * dz\n z1 = Math.ceil(z1 / dz) * dz\n\n const projection = mat4.ortho(mat4.create(), x0, x0 + w, y0, y0 + h, -z1, -z0)\n const viewProjection = new Mat4()\n mat4.multiply(viewProjection, projection, view)\n return { viewProjection, texelSize: Math.max(w, h) / size }\n}\n\n/** A length rounded up to the next of a ladder of sizes, sixteen to each doubling. @param {number} v */\nfunction steps(v) {\n return 2 ** (Math.ceil(Math.log2(Math.max(v, 1e-3)) * 16) / 16)\n}\n\n/** Spot shadows' map: four tiles of half its size, one a light. */\nexport const SPOT_ATLAS_SIZE = 2048\nexport const SPOT_TILES = 4\n\n/**\n * A spot light's view for its shadow: from the light along its cone, wide enough for the cone,\n * from just short of the nearest caster to the furthest receiver (or the light's range).\n * @param {ArrayLike<number>} position @param {ArrayLike<number>} direction\n * @param {number} angle the cone's half-angle @param {number} range 0 for unlimited\n * @param {Box3[]} casters @param {Box3[]} receivers\n * @returns {{ viewProjection: Mat4, texelAngle: number } | null} texelAngle: a shadow map texel's size at a distance of 1\n */\nexport function fitSpotShadow(position, direction, angle, range, casters, receivers) {\n const boxes = casters.filter((b) => !b.isEmpty())\n if (!boxes.length) return null\n const d = normalized(direction)\n const up = Math.abs(d[1]) > 0.99 ? [0, 0, 1] : [0, 1, 0]\n const eye = Float32Array.from(position), at = Float32Array.from([position[0] + d[0], position[1] + d[1], position[2] + d[2]])\n const view = mat4.lookAt(mat4.create(), eye, at, Float32Array.from(up))\n let near = Infinity, far = 0\n const depths = (/** @type {Box3} */ b, /** @type {boolean} */ caster) => {\n for (let i = 0; i < 8; i++) {\n const px = i & 1 ? b.max[0] : b.min[0], py = i & 2 ? b.max[1] : b.min[1], pz = i & 4 ? b.max[2] : b.min[2]\n const z = -(view[2] * px + view[6] * py + view[10] * pz + view[14])\n if (caster && z < near) near = z\n if (z > far) far = z\n }\n }\n for (const b of boxes) depths(b, true)\n for (const b of receivers) if (!b.isEmpty()) depths(b, false)\n near = Math.max(0.05, near * 0.9)\n if (range > 0) far = Math.min(far, range)\n far = Math.max(far * 1.02, near * 2)\n // a little wider than the cone, so its soft edge isn't cut off\n const fov = Math.min(2 * angle * 1.1 + 0.05, Math.PI * 0.95)\n const projection = mat4.perspective(mat4.create(), fov, 1, near, far)\n const viewProjection = new Mat4()\n mat4.multiply(viewProjection, projection, view)\n return { viewProjection, texelAngle: 2 * Math.tan(fov / 2) / (SPOT_ATLAS_SIZE / 2) }\n}\n\n/** A point light's shadow: a cube of six square faces, each this many texels across. */\nexport const POINT_SHADOW_SIZE = 1024\n\n// the cube's faces in GL's order (+X, -X, +Y, -Y, +Z, -Z): which way each looks, and its up -\n// upside down, as cube maps are stored\nconst CUBE_FACES = [\n [[1, 0, 0], [0, -1, 0]], [[-1, 0, 0], [0, -1, 0]],\n [[0, 1, 0], [0, 0, 1]], [[0, -1, 0], [0, 0, -1]],\n [[0, 0, 1], [0, -1, 0]], [[0, 0, -1], [0, -1, 0]],\n]\n\n/**\n * A point light's six views for its shadow, a right angle each, from close to the light out to the\n * furthest receiver (or the light's range). Null when nothing casts.\n * @param {ArrayLike<number>} position @param {number} range 0 for unlimited\n * @param {Box3[]} casters @param {Box3[]} receivers\n * @returns {{ viewProjections: Mat4[], near: number, far: number, texelAngle: number } | null} texelAngle: a texel's size at a distance of 1\n */\nexport function fitPointShadow(position, range, casters, receivers) {\n const boxes = casters.filter((b) => !b.isEmpty())\n if (!boxes.length) return null\n // out to the furthest corner of anything casting or receiving\n let far = 0\n for (const b of [...boxes, ...receivers]) {\n if (b.isEmpty()) continue\n for (let i = 0; i < 8; i++) {\n const dx = (i & 1 ? b.max[0] : b.min[0]) - position[0]\n const dy = (i & 2 ? b.max[1] : b.min[1]) - position[1]\n const dz = (i & 4 ? b.max[2] : b.min[2]) - position[2]\n far = Math.max(far, Math.hypot(dx, dy, dz))\n }\n }\n if (range > 0) far = Math.min(far, range)\n far = Math.max(far * 1.02, 1e-3)\n // a caster can wrap the light - a lantern, a pumpkin - so the near plane can't wait for the\n // nearest caster; a fraction of the far one keeps the depth precise\n const near = far * 2e-3\n const projection = mat4.perspective(mat4.create(), Math.PI / 2, 1, near, far)\n const eye = Float32Array.from(position)\n const viewProjections = CUBE_FACES.map(([d, up]) => {\n const at = Float32Array.from([eye[0] + d[0], eye[1] + d[1], eye[2] + d[2]])\n const view = mat4.lookAt(mat4.create(), eye, at, Float32Array.from(up))\n return /** @type {Mat4} */ (mat4.multiply(new Mat4(), projection, view))\n })\n return { viewProjections, near, far, texelAngle: 2 / POINT_SHADOW_SIZE }\n}\n\n/** @param {ArrayLike<number>} v @returns {number[]} */\nfunction normalized(v) {\n const len = Math.hypot(v[0], v[1], v[2]) || 1\n return [v[0] / len, v[1] / len, v[2] / len]\n}\n","// The 148 CSS named colours (CSS Color Module Level 4), as name:rrggbb pairs. Kept as one string\n// because it compresses far better than an object literal.\nconst TABLE =\n 'aliceblue:f0f8ff,antiquewhite:faebd7,aqua:00ffff,aquamarine:7fffd4,azure:f0ffff,beige:f5f5dc,' +\n 'bisque:ffe4c4,black:000000,blanchedalmond:ffebcd,blue:0000ff,blueviolet:8a2be2,brown:a52a2a,' +\n 'burlywood:deb887,cadetblue:5f9ea0,chartreuse:7fff00,chocolate:d2691e,coral:ff7f50,' +\n 'cornflowerblue:6495ed,cornsilk:fff8dc,crimson:dc143c,cyan:00ffff,darkblue:00008b,darkcyan:008b8b,' +\n 'darkgoldenrod:b8860b,darkgray:a9a9a9,darkgreen:006400,darkgrey:a9a9a9,darkkhaki:bdb76b,' +\n 'darkmagenta:8b008b,darkolivegreen:556b2f,darkorange:ff8c00,darkorchid:9932cc,darkred:8b0000,' +\n 'darksalmon:e9967a,darkseagreen:8fbc8f,darkslateblue:483d8b,darkslategray:2f4f4f,' +\n 'darkslategrey:2f4f4f,darkturquoise:00ced1,darkviolet:9400d3,deeppink:ff1493,deepskyblue:00bfff,' +\n 'dimgray:696969,dimgrey:696969,dodgerblue:1e90ff,firebrick:b22222,floralwhite:fffaf0,' +\n 'forestgreen:228b22,fuchsia:ff00ff,gainsboro:dcdcdc,ghostwhite:f8f8ff,gold:ffd700,goldenrod:daa520,' +\n 'gray:808080,green:008000,greenyellow:adff2f,grey:808080,honeydew:f0fff0,hotpink:ff69b4,' +\n 'indianred:cd5c5c,indigo:4b0082,ivory:fffff0,khaki:f0e68c,lavender:e6e6fa,lavenderblush:fff0f5,' +\n 'lawngreen:7cfc00,lemonchiffon:fffacd,lightblue:add8e6,lightcoral:f08080,lightcyan:e0ffff,' +\n 'lightgoldenrodyellow:fafad2,lightgray:d3d3d3,lightgreen:90ee90,lightgrey:d3d3d3,lightpink:ffb6c1,' +\n 'lightsalmon:ffa07a,lightseagreen:20b2aa,lightskyblue:87cefa,lightslategray:778899,' +\n 'lightslategrey:778899,lightsteelblue:b0c4de,lightyellow:ffffe0,lime:00ff00,limegreen:32cd32,' +\n 'linen:faf0e6,magenta:ff00ff,maroon:800000,mediumaquamarine:66cdaa,mediumblue:0000cd,' +\n 'mediumorchid:ba55d3,mediumpurple:9370db,mediumseagreen:3cb371,mediumslateblue:7b68ee,' +\n 'mediumspringgreen:00fa9a,mediumturquoise:48d1cc,mediumvioletred:c71585,midnightblue:191970,' +\n 'mintcream:f5fffa,mistyrose:ffe4e1,moccasin:ffe4b5,navajowhite:ffdead,navy:000080,oldlace:fdf5e6,' +\n 'olive:808000,olivedrab:6b8e23,orange:ffa500,orangered:ff4500,orchid:da70d6,palegoldenrod:eee8aa,' +\n 'palegreen:98fb98,paleturquoise:afeeee,palevioletred:db7093,papayawhip:ffefd5,peachpuff:ffdab9,' +\n 'peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple:800080,rebeccapurple:663399,' +\n 'red:ff0000,rosybrown:bc8f8f,royalblue:4169e1,saddlebrown:8b4513,salmon:fa8072,sandybrown:f4a460,' +\n 'seagreen:2e8b57,seashell:fff5ee,sienna:a0522d,silver:c0c0c0,skyblue:87ceeb,slateblue:6a5acd,' +\n 'slategray:708090,slategrey:708090,snow:fffafa,springgreen:00ff7f,steelblue:4682b4,tan:d2b48c,' +\n 'teal:008080,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,' +\n 'white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32'\n\n/** CSS colour name -> 0xrrggbb. @type {Map<string, number>} */\nexport const CSS_COLORS = new Map(TABLE.split(',').map((pair) => {\n const [name, hex] = pair.split(':')\n return [name, parseInt(hex, 16)]\n}))\n","import { describe, didYouMean, fail } from '../validate.js'\nimport { CSS_COLORS } from './cssColors.js'\n\n/** @import { ColorInput } from '../types.js' */\n\nconst toLinear = (c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4)\nconst toSRGB = (c) => (c <= 0.0031308 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055)\nconst clamp01 = (c) => Math.min(1, Math.max(0, c))\n\nconst NUMBER = String.raw`[-+]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?`\nconst FUNC = new RegExp(String.raw`^(rgba?|hsla?)\\(\\s*(${NUMBER})(%|deg)?[\\s,]+(${NUMBER})(%)?[\\s,]+(${NUMBER})(%)?(?:\\s*[,/]\\s*(${NUMBER})%?)?\\s*\\)$`, 'i')\n\nconst HELP = \"use '#rrggbb', a CSS name, 'rgb(...)', 'hsl(...)', 0xrrggbb or [r, g, b] with components 0-1\"\n\n/**\n * An RGB colour. Input is sRGB, as everywhere in phoria2; the components are stored **linear**,\n * ready for lighting maths. `toJSON()` gives sRGB '#rrggbb' back.\n */\n// colour strings already worked out, as linear rgb - emptied when full, as a palette never fills it\n/** @type {Map<string, number[]>} */\nconst PARSED = new Map()\nconst PARSED_MAX = 1024\n\nexport class Color extends Float32Array {\n static get [Symbol.species]() { return Float32Array }\n\n /** @param {ColorInput} [input] defaults to white */\n constructor(input = 0xffffff) {\n super(3)\n this.set(input)\n }\n\n /** @internal @param {ColorInput} input @param {string} [owner] for error messages @returns {Color} */\n static fromInput(input, owner = 'Color') {\n return new Color().set(input, owner)\n }\n\n /** Linear red. */\n get r() { return this[0] }\n set r(v) { this[0] = v }\n get g() { return this[1] }\n set g(v) { this[1] = v }\n get b() { return this[2] }\n set b(v) { this[2] = v }\n\n /**\n * Set from any colour input (sRGB).\n * @overload\n * @param {ColorInput} input @param {string} [owner]\n * @returns {this}\n */\n /**\n * @overload\n * @param {ArrayLike<number>} array @param {number} [offset]\n * @returns {void}\n */\n /** @param {any} input @param {any} [owner] */\n set(input, owner = 'Color') {\n if (typeof owner === 'number') {\n // typed array set(array, offset)\n super.set(input, owner)\n return\n }\n if (input instanceof Color) {\n this[0] = input[0]\n this[1] = input[1]\n this[2] = input[2]\n } else if (typeof input === 'number') {\n this.#setHex(input, owner)\n } else if (typeof input === 'string') {\n this.#setString(input.trim(), owner)\n } else if (Array.isArray(input) || ArrayBuffer.isView(input)) {\n const arr = /** @type {ArrayLike<number>} */ (input)\n if (arr.length < 3) fail(owner, `color ${describe(input)} needs 3 components [r, g, b]`)\n const r = arr[0], g = arr[1], b = arr[2]\n if ([r, g, b].some((c) => typeof c !== 'number' || Number.isNaN(c))) fail(owner, `color components must be numbers - ${HELP}`)\n if (r > 1 || g > 1 || b > 1) {\n fail(owner, `color [${r}, ${g}, ${b}] has components above 1 - components are 0-1, ` +\n `e.g. [${+(r / 255).toFixed(3)}, ${+(g / 255).toFixed(3)}, ${+(b / 255).toFixed(3)}]`)\n }\n this.setSRGB(r, g, b)\n } else {\n fail(owner, `${describe(input)} is not a colour - ${HELP}`)\n }\n return this\n }\n\n /** Set from sRGB components 0-1. @param {number} r @param {number} g @param {number} b @returns {this} */\n setSRGB(r, g, b) {\n this[0] = toLinear(r)\n this[1] = toLinear(g)\n this[2] = toLinear(b)\n return this\n }\n\n /** Set linear components directly. @param {number} r @param {number} g @param {number} b @returns {this} */\n setLinear(r, g, b) {\n this[0] = r\n this[1] = g\n this[2] = b\n return this\n }\n\n /** @returns {Color} */\n clone() {\n return new Color(this)\n }\n\n /** @param {number} s @returns {this} */\n multiplyScalar(s) {\n this[0] *= s\n this[1] *= s\n this[2] *= s\n return this\n }\n\n /**\n * Move towards another colour by t (0-1), mixing the linear components - as light mixes.\n * @param {ColorInput} c @param {number} t @returns {this}\n */\n lerp(c, t) {\n const o = c instanceof Color ? c : Color.fromInput(c)\n this[0] += (o[0] - this[0]) * t\n this[1] += (o[1] - this[1]) * t\n this[2] += (o[2] - this[2]) * t\n return this\n }\n\n /** sRGB components 0-1. @returns {[number, number, number]} */\n toSRGB() {\n return [clamp01(toSRGB(this[0])), clamp01(toSRGB(this[1])), clamp01(toSRGB(this[2]))]\n }\n\n /** sRGB as 0xrrggbb. @returns {number} */\n getHex() {\n const [r, g, b] = this.toSRGB()\n return (Math.round(r * 255) << 16) | (Math.round(g * 255) << 8) | Math.round(b * 255)\n }\n\n /** sRGB as '#rrggbb'. @returns {string} */\n getStyle() {\n return '#' + this.getHex().toString(16).padStart(6, '0')\n }\n\n /** @param {Color} c @param {number} [epsilon] @returns {boolean} */\n equals(c, epsilon = 1e-6) {\n return Math.abs(this[0] - c[0]) <= epsilon && Math.abs(this[1] - c[1]) <= epsilon && Math.abs(this[2] - c[2]) <= epsilon\n }\n\n toJSON() {\n return this.getStyle()\n }\n\n /** @param {number} hex @param {string} owner */\n #setHex(hex, owner) {\n if (!Number.isInteger(hex) || hex < 0 || hex > 0xffffff) fail(owner, `color ${hex} is not 0x000000-0xffffff - ${HELP}`)\n this.setSRGB(((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255)\n }\n\n /** @param {string} s @param {string} owner */\n #setString(s, owner) {\n // the same few strings come again and again - an instance's colour set every frame - so each is\n // worked out once\n const known = PARSED.get(s)\n if (known) {\n this[0] = known[0]\n this[1] = known[1]\n this[2] = known[2]\n return\n }\n this.#parse(s, owner)\n if (PARSED.size >= PARSED_MAX) PARSED.clear()\n PARSED.set(s, [this[0], this[1], this[2]])\n }\n\n /** @param {string} s @param {string} owner */\n #parse(s, owner) {\n const lower = s.toLowerCase()\n if (lower.startsWith('#')) {\n let hex = lower.slice(1)\n if (/^[0-9a-f]{3,4}$/.test(hex)) hex = [...hex.slice(0, 3)].map((c) => c + c).join('')\n else if (/^[0-9a-f]{8}$/.test(hex)) hex = hex.slice(0, 6)\n if (!/^[0-9a-f]{6}$/.test(hex)) fail(owner, `color '${s}' is not a valid hex colour - ${HELP}`)\n this.#setHex(parseInt(hex, 16), owner)\n return\n }\n const named = CSS_COLORS.get(lower)\n if (named !== undefined) {\n this.#setHex(named, owner)\n return\n }\n const m = FUNC.exec(s)\n if (!m) fail(owner, `'${s}' is not a colour${didYouMean(lower, CSS_COLORS.keys())} - ${HELP}`)\n const [, fn, a, aUnit, b, bUnit, c, cUnit] = m\n if (fn.toLowerCase().startsWith('rgb')) {\n const channel = (v, unit) => clamp01(unit === '%' ? +v / 100 : +v / 255)\n this.setSRGB(channel(a, aUnit), channel(b, bUnit), channel(c, cUnit))\n } else {\n // hsl: hue in degrees, saturation and lightness in percent\n const h = (((+a % 360) + 360) % 360) / 360\n const sat = clamp01(+b / 100), light = clamp01(+c / 100)\n const q = light < 0.5 ? light * (1 + sat) : light + sat - light * sat\n const p = 2 * light - q\n const hue = (t) => {\n t = (t + 1) % 1\n if (t < 1 / 6) return p + (q - p) * 6 * t\n if (t < 1 / 2) return q\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n return p\n }\n this.setSRGB(hue(h + 1 / 3), hue(h), hue(h - 1 / 3))\n }\n }\n}\n","// Section planes: a node's `clip` cuts away everything in its subtree on one side of a plane, for\n// cutaways - an engine with its block opened up, a building with a wall off. The plane lives in the\n// node's own space, so it moves and turns with the node. Drawing, shadows, picking and the\n// raycaster all leave out what is cut away; a cap colour fills the cut faces of closed shapes - a\n// surface lying on the plane itself, so parts that touch join cleanly and what's inside stays hidden.\nimport { Color } from './value/Color.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { checkNumber, checkOptions, describe, fail } from './validate.js'\n\n/** @import { ColorInput, Vec3Input } from './types.js' */\n/** @import { Node } from './scene/Node.js' */\n\n/**\n * @typedef {object} ClipOptions\n * @property {Vec3Input} [normal] the side of the plane that is cut away, in the node's own space\n * (default [0, 0, 1]: the front, towards a camera that hasn't moved)\n * @property {number} [offset] how far along the normal from the node's origin the plane lies (default 0)\n * @property {ColorInput | null} [cap] fill colour for the cut faces of closed shapes, lit as a flat\n * face on the plane; null leaves them open, showing the inside (default null). Caps need closed\n * solids: an open surface (a plane, an open tube) under a capped clip would fill in wrongly\n */\n\nexport const CLIP_OPTIONS = ['normal', 'offset', 'cap']\nexport const CLIP_HINTS = {\n constant: \"use 'offset' for how far along the normal the plane is\",\n distance: \"use 'offset' for how far along the normal the plane is\",\n plane: \"give the plane as 'normal' and 'offset'\",\n color: \"use 'cap' for the colour of the cut faces\",\n capColor: \"use 'cap' for the colour of the cut faces\",\n}\n\n/** A section plane, as a node's `clip`: change its numbers in place to move the cut. */\nexport class Clip {\n /** Which side is cut away, in the node's space; any length. @type {Vec3} */ normal = new Vec3(0, 0, 1)\n /** How far along the normal from the node's origin the plane is. */ offset = 0\n /** Fill colour for cut faces of closed shapes, or null for none. @type {Color | null} */ cap = null\n\n /** @param {ClipOptions} [options] */\n constructor(options = {}) {\n checkOptions('clip', options, CLIP_OPTIONS, CLIP_HINTS)\n if (options.normal !== undefined) this.normal.copy(options.normal, 'clip')\n if (!(Math.hypot(this.normal[0], this.normal[1], this.normal[2]) > 0)) fail('clip', \"'normal' can't be [0, 0, 0] - it says which side is cut away\")\n if (options.offset !== undefined) this.offset = checkNumber('clip', 'offset', options.offset)\n if (options.cap != null) this.cap = Color.fromInput(options.cap, 'clip')\n }\n\n /** @internal\n * A Clip from a Clip (returned as is) or options.\n * @param {Clip | ClipOptions} input @param {string} [owner]\n * @returns {Clip}\n */\n static fromInput(input, owner = 'clip') {\n if (input instanceof Clip) return input\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n fail(owner, `'clip' must be { normal, offset, cap } or null, got ${describe(input)}`)\n }\n return new Clip(input)\n }\n\n /** @returns {ClipOptions} */\n toJSON() {\n /** @type {ClipOptions} */\n const json = { normal: this.normal.toArray(), offset: this.offset }\n if (this.cap) json.cap = this.cap.getStyle()\n return json\n }\n}\n\n/**\n * The plane of a node's clip in world space, as [nx, ny, nz, d] with a unit normal: a point p is\n * cut away where n.p + d > 0. Uses the node's world matrix as it stands.\n * @param {Node} node a node with a clip\n * @param {Float32Array} [out]\n * @returns {Float32Array}\n */\nexport function worldPlane(node, out = new Float32Array(4)) {\n const clip = /** @type {Clip} */ (node.clip), m = node.worldMatrix\n const [x, y, z] = clip.normal, l = Math.hypot(x, y, z)\n const nx = x / l, ny = y / l, nz = z / l\n // a point on the plane, and the normal through the inverse transpose - as a plane, [n, d] times\n // the inverse world matrix, which for the normal is its cofactors\n const px = nx * clip.offset, py = ny * clip.offset, pz = nz * clip.offset\n const wx = m[0] * px + m[4] * py + m[8] * pz + m[12], wy = m[1] * px + m[5] * py + m[9] * pz + m[13], wz = m[2] * px + m[6] * py + m[10] * pz + m[14]\n const c0 = [m[5] * m[10] - m[6] * m[9], m[6] * m[8] - m[4] * m[10], m[4] * m[9] - m[5] * m[8]]\n const c1 = [m[2] * m[9] - m[1] * m[10], m[0] * m[10] - m[2] * m[8], m[1] * m[8] - m[0] * m[9]]\n const c2 = [m[1] * m[6] - m[2] * m[5], m[2] * m[4] - m[0] * m[6], m[0] * m[5] - m[1] * m[4]]\n let ox = c0[0] * nx + c1[0] * ny + c2[0] * nz, oy = c0[1] * nx + c1[1] * ny + c2[1] * nz, oz = c0[2] * nx + c1[2] * ny + c2[2] * nz\n // a mirroring transform flips the cofactors' sign; keep the normal on the cut-away side\n const det = m[0] * c0[0] + m[4] * c1[0] + m[8] * c2[0]\n const s = (det < 0 ? -1 : 1) / (Math.hypot(ox, oy, oz) || 1)\n ox *= s\n oy *= s\n oz *= s\n out[0] = ox\n out[1] = oy\n out[2] = oz\n out[3] = -(ox * wx + oy * wy + oz * wz)\n return out\n}\n\n/** The nearest node at or above this one with a clip - the one that cuts it - or null. @param {Node | null} node */\nexport function clipOwner(node) {\n for (let n = node; n; n = n.parent) if (n.clip) return n\n return null\n}\n","import { describe, fail } from '../validate.js'\n\n/**\n * Euler angles in radians, applied in XYZ order (three.js's default). A node's `rotation` is an\n * Euler kept in sync with its `quaternion`: `node.rotation.y += 0.01` works as expected.\n */\nexport class Euler {\n #x = 0\n #y = 0\n #z = 0\n\n /** Only XYZ is supported. */\n get order() { return 'XYZ' }\n\n /** @internal Called after any change. @type {(() => void) | null} */\n onChange = null\n\n /** @param {number} [x] @param {number} [y] @param {number} [z] */\n constructor(x = 0, y = 0, z = 0) {\n this.#x = x\n this.#y = y\n this.#z = z\n }\n\n get x() { return this.#x }\n set x(v) { this.#x = v; this.onChange?.() }\n get y() { return this.#y }\n set y(v) { this.#y = v; this.onChange?.() }\n get z() { return this.#z }\n set z(v) { this.#z = v; this.onChange?.() }\n\n /** @param {number} x @param {number} y @param {number} z @returns {this} */\n set(x, y, z) {\n this.#x = x\n this.#y = y\n this.#z = z\n this.onChange?.()\n return this\n }\n\n /** @param {Euler | ArrayLike<number>} e [x, y, z] @param {string} [owner] @returns {this} */\n copy(e, owner = 'Euler') {\n if (e instanceof Euler) return this.set(e.x, e.y, e.z)\n if (!e || typeof e !== 'object' || !(e.length >= 3)) fail(owner, `expected rotation angles [x, y, z] in radians, got ${describe(e)}`)\n return this.set(e[0], e[1], e[2])\n }\n\n /** @returns {Euler} */\n clone() {\n return new Euler(this.#x, this.#y, this.#z)\n }\n\n /**\n * The XYZ angles of a quaternion, without firing onChange (used to sync from a node's quaternion).\n * @param {ArrayLike<number>} q\n * @returns {this}\n */\n setFromQuat(q) {\n const x = q[0], y = q[1], z = q[2], w = q[3]\n // elements of the rotation matrix the angles are read from\n const m11 = 1 - 2 * (y * y + z * z), m12 = 2 * (x * y - z * w), m13 = 2 * (x * z + y * w)\n const m22 = 1 - 2 * (x * x + z * z), m23 = 2 * (y * z - x * w)\n const m32 = 2 * (y * z + x * w), m33 = 1 - 2 * (x * x + y * y)\n this.#y = Math.asin(Math.min(1, Math.max(-1, m13)))\n if (Math.abs(m13) < 0.9999999) {\n this.#x = Math.atan2(-m23, m33)\n this.#z = Math.atan2(-m12, m11)\n } else {\n // gimbal lock: x and z rotate about the same axis\n this.#x = Math.atan2(m32, m22)\n this.#z = 0\n }\n return this\n }\n\n /** @returns {[number, number, number]} */\n toArray() {\n return [this.#x, this.#y, this.#z]\n }\n\n toJSON() {\n return this.toArray()\n }\n\n *[Symbol.iterator]() {\n yield this.#x\n yield this.#y\n yield this.#z\n }\n}\n","// Quaternions as Float32Array(4) [x, y, z, w]. Signatures follow gl-matrix.\n\n/** @returns {Float32Array} identity quaternion */\nexport function create() {\n const out = new Float32Array(4)\n out[3] = 1\n return out\n}\n\n/** @param {number} x @param {number} y @param {number} z @param {number} w @returns {Float32Array} */\nexport function fromValues(x, y, z, w) {\n const out = new Float32Array(4)\n out[0] = x\n out[1] = y\n out[2] = z\n out[3] = w\n return out\n}\n\n/** Rotation of `rad` radians about a normalised axis. @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} axis @param {number} rad @returns {T} */\nexport function setAxisAngle(out, axis, rad) {\n const s = Math.sin(rad * 0.5)\n out[0] = s * axis[0]\n out[1] = s * axis[1]\n out[2] = s * axis[2]\n out[3] = Math.cos(rad * 0.5)\n return out\n}\n\n/** out = a * b (apply b, then a) @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @param {Float32Array | number[]} b @returns {T} */\nexport function multiply(out, a, b) {\n const ax = a[0], ay = a[1], az = a[2], aw = a[3]\n const bx = b[0], by = b[1], bz = b[2], bw = b[3]\n out[0] = ax * bw + aw * bx + ay * bz - az * by\n out[1] = ay * bw + aw * by + az * bx - ax * bz\n out[2] = az * bw + aw * bz + ax * by - ay * bx\n out[3] = aw * bw - ax * bx - ay * by - az * bz\n return out\n}\n\n/** @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @returns {T} */\nexport function normalize(out, a) {\n const x = a[0], y = a[1], z = a[2], w = a[3]\n let len = x * x + y * y + z * z + w * w\n if (len > 0) len = 1 / Math.sqrt(len)\n out[0] = x * len\n out[1] = y * len\n out[2] = z * len\n out[3] = w * len\n return out\n}\n\n/** @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @returns {T} */\nexport function invert(out, a) {\n const x = a[0], y = a[1], z = a[2], w = a[3]\n const dot = x * x + y * y + z * z + w * w\n const inv = dot ? 1 / dot : 0\n out[0] = -x * inv\n out[1] = -y * inv\n out[2] = -z * inv\n out[3] = w * inv\n return out\n}\n\n/** Spherical interpolation, taking the short way round. @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @param {Float32Array | number[]} b @param {number} t @returns {T} */\nexport function slerp(out, a, b, t) {\n const ax = a[0], ay = a[1], az = a[2], aw = a[3]\n let bx = b[0], by = b[1], bz = b[2], bw = b[3]\n let cosom = ax * bx + ay * by + az * bz + aw * bw\n if (cosom < 0) {\n cosom = -cosom\n bx = -bx; by = -by; bz = -bz; bw = -bw\n }\n let s0 = 1 - t, s1 = t\n if (1 - cosom > 0.000001) {\n const omega = Math.acos(cosom), sinom = Math.sin(omega)\n s0 = Math.sin((1 - t) * omega) / sinom\n s1 = Math.sin(t * omega) / sinom\n }\n out[0] = s0 * ax + s1 * bx\n out[1] = s0 * ay + s1 * by\n out[2] = s0 * az + s1 * bz\n out[3] = s0 * aw + s1 * bw\n return out\n}\n\n// Ken Shoemake's algorithm, as in gl-matrix. The matrix must be a pure rotation.\n/** @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} m 3x3 column-major @returns {T} */\nexport function fromMat3(out, m) {\n const trace = m[0] + m[4] + m[8]\n if (trace > 0) {\n let root = Math.sqrt(trace + 1)\n out[3] = 0.5 * root\n root = 0.5 / root\n out[0] = (m[5] - m[7]) * root\n out[1] = (m[6] - m[2]) * root\n out[2] = (m[1] - m[3]) * root\n } else {\n let i = 0\n if (m[4] > m[0]) i = 1\n if (m[8] > m[i * 3 + i]) i = 2\n const j = (i + 1) % 3, k = (i + 2) % 3\n let root = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1)\n out[i] = 0.5 * root\n root = 0.5 / root\n out[3] = (m[j * 3 + k] - m[k * 3 + j]) * root\n out[j] = (m[j * 3 + i] + m[i * 3 + j]) * root\n out[k] = (m[k * 3 + i] + m[i * 3 + k]) * root\n }\n return out\n}\n\n// Euler angles (radians) applied in XYZ order - the same convention as three.js's default.\n/** @template {Float32Array | number[]} T @param {T} out @param {number} x @param {number} y @param {number} z @returns {T} */\nexport function fromEulerXYZ(out, x, y, z) {\n const c1 = Math.cos(x / 2), c2 = Math.cos(y / 2), c3 = Math.cos(z / 2)\n const s1 = Math.sin(x / 2), s2 = Math.sin(y / 2), s3 = Math.sin(z / 2)\n out[0] = s1 * c2 * c3 + c1 * s2 * s3\n out[1] = c1 * s2 * c3 - s1 * c2 * s3\n out[2] = c1 * c2 * s3 + s1 * s2 * c3\n out[3] = c1 * c2 * c3 - s1 * s2 * s3\n return out\n}\n","import * as quat from '../math/quat.js'\nimport { describe, fail } from '../validate.js'\n\n/** @import { QuatInput } from '../types.js' */\n\n/**\n * A rotation quaternion [x, y, z, w]: a Float32Array(4) with accessors and chainable methods.\n * A node's quaternion and its Euler `rotation` keep each other in sync through these setters;\n * writing by index (e.g. passing it as `out` to a quat function) does not, so call `changed()`\n * afterwards when doing that.\n */\nexport class Quat extends Float32Array {\n static get [Symbol.species]() { return Float32Array }\n\n /** @internal Called after any change made through the methods below. @type {(() => void) | null} */\n onChange = null\n\n /** @param {number} [x] @param {number} [y] @param {number} [z] @param {number} [w] */\n constructor(x = 0, y = 0, z = 0, w = 1) {\n super(4)\n this[0] = x\n this[1] = y\n this[2] = z\n this[3] = w\n }\n\n get x() { return this[0] }\n set x(v) { this[0] = v; this.changed() }\n get y() { return this[1] }\n set y(v) { this[1] = v; this.changed() }\n get z() { return this[2] }\n set z(v) { this[2] = v; this.changed() }\n get w() { return this[3] }\n set w(v) { this[3] = v; this.changed() }\n\n /** @internal Notify the owner after editing by index. @returns {this} */\n changed() {\n this.onChange?.()\n return this\n }\n\n /**\n * @overload\n * @param {number} x @param {number} y @param {number} z @param {number} w\n * @returns {this}\n */\n /**\n * @overload\n * @param {ArrayLike<number>} array @param {number} [offset]\n * @returns {void}\n */\n /** @param {number | ArrayLike<number>} x @param {number} [y] @param {number} [z] @param {number} [w] */\n set(x, y, z, w) {\n if (typeof x !== 'number') {\n super.set(x, y ?? 0)\n this.changed()\n return\n }\n this[0] = x\n this[1] = y\n this[2] = z\n this[3] = w\n return this.changed()\n }\n\n /** @param {QuatInput} q [x, y, z, w], or { x, y, z, w } as physics engines give them @param {string} [owner] @returns {this} */\n copy(q, owner = 'Quat') {\n const o = /** @type {any} */ (q)\n if (o && typeof o === 'object' && o.length >= 4) {\n this[0] = o[0]\n this[1] = o[1]\n this[2] = o[2]\n this[3] = o[3]\n } else if (o && typeof o === 'object' && 'x' in o && 'y' in o && 'z' in o && 'w' in o) {\n this[0] = o.x\n this[1] = o.y\n this[2] = o.z\n this[3] = o.w\n } else fail(owner, `expected a quaternion [x, y, z, w] or { x, y, z, w }, got ${describe(q)}`)\n return this.changed()\n }\n\n /** @returns {Quat} */\n clone() {\n return new Quat(this[0], this[1], this[2], this[3])\n }\n\n /** @returns {this} */\n identity() {\n return this.set(0, 0, 0, 1)\n }\n\n /** Euler angles in radians, XYZ order. @param {number} x @param {number} y @param {number} z @returns {this} */\n setFromEuler(x, y, z) {\n quat.fromEulerXYZ(this, x, y, z)\n return this.changed()\n }\n\n /** @param {ArrayLike<number>} axis normalised @param {number} rad @returns {this} */\n setFromAxisAngle(axis, rad) {\n quat.setAxisAngle(this, /** @type {number[]} */ (axis), rad)\n return this.changed()\n }\n\n /** this = this * q (rotate by q in the local frame) @param {ArrayLike<number>} q @returns {this} */\n multiply(q) {\n quat.multiply(this, this, /** @type {number[]} */ (q))\n return this.changed()\n }\n\n /** this = q * this (rotate by q in the parent frame) @param {ArrayLike<number>} q @returns {this} */\n premultiply(q) {\n quat.multiply(this, /** @type {number[]} */ (q), this)\n return this.changed()\n }\n\n /** @returns {this} */\n normalize() {\n quat.normalize(this, this)\n return this.changed()\n }\n\n /** @returns {this} */\n invert() {\n quat.invert(this, this)\n return this.changed()\n }\n\n /** @param {ArrayLike<number>} q @param {number} t @returns {this} */\n slerp(q, t) {\n quat.slerp(this, this, /** @type {number[]} */ (q), t)\n return this.changed()\n }\n\n /** @returns {[number, number, number, number]} */\n toArray() {\n return [this[0], this[1], this[2], this[3]]\n }\n\n toJSON() {\n return this.toArray()\n }\n}\n","import { Box3 } from '../value/Box3.js'\nimport { checkOptions, describe, fail } from '../validate.js'\n\n/**\n * @typedef {object} GeometryOptions\n * @property {ArrayLike<number>} positions xyz per vertex\n * @property {ArrayLike<number>} [normals] xyz per vertex; computed (smooth) when missing\n * @property {ArrayLike<number>} [uvs] uv per vertex - glTF convention, (0, 0) is the image's top left\n * @property {ArrayLike<number>} [uvs2] a second uv per vertex, for maps that need every surface on its own\n * patch of texture - baked occlusion and light maps (a texture's uvSet: 1 reads it)\n * @property {ArrayLike<number>} [colors] rgb per vertex, sRGB 0-1 like every colour input\n * @property {ArrayLike<number>} [sizes] points: one per vertex, a multiple of the material's size\n * @property {ArrayLike<number>} [opacities] points: one per vertex, 0-1, multiplying the material's opacity\n * @property {ArrayLike<number>} [angles] points: one per vertex, radians anticlockwise on screen - turns\n * each point's texture\n * @property {ArrayLike<number>} [indices] vertex indices; triangles for meshes, pairs for lines\n */\n\nconst OPTIONS = ['positions', 'normals', 'uvs', 'uvs2', 'colors', 'sizes', 'opacities', 'angles', 'indices']\n// the per-point arrays: Points with any of them draw each point as its own square, sized, faded and turned\nconst POINT_ARRAYS = /** @type {const} */ (['sizes', 'opacities', 'angles'])\n\n/**\n * Vertex data: flat typed arrays plus an optional index. Generators such as box() and sphere()\n * return one; build your own from arrays. Change the arrays in place and call needsUpdate().\n */\nexport class Geometry {\n /** The options it takes. */\n static OPTIONS = OPTIONS\n /** @type {Float32Array} */ positions\n /** @type {Float32Array | null} */ uvs = null\n /** A second UV set, for baked occlusion and light maps. @type {Float32Array | null} */ uvs2 = null\n /** @type {Float32Array | null} */ colors = null\n /** Points: each one's size, as a multiple of the material's. @type {Float32Array | null} */ sizes = null\n /** Points: each one's opacity, 0-1, times the material's. @type {Float32Array | null} */ opacities = null\n /** Points: each one's turn on screen, in radians anticlockwise. @type {Float32Array | null} */ angles = null\n /** @type {Uint16Array | Uint32Array | null} */ indices = null\n\n /** @internal Bumped by needsUpdate() so renderers know to re-upload. */\n version = 0\n\n /**\n * Draw only the first `drawCount` vertices (indices, when indexed), or all of them when null -\n * for geometry that fills up over time, such as particles. Picking honours it too.\n * @type {number | null}\n */\n drawCount = null\n\n /**\n * How this geometry was made, when it came from a generator - lets toJSON() stay small.\n * @type {{ type: string } & Record<string, unknown> | null}\n */\n source = null\n\n /** @type {Float32Array | null} */\n #normals = null\n /** The normals were worked out on first read, rather than given or asked for: they follow the shape. */\n #autoNormals = false\n /** @type {Box3 | null} */\n #bounds = null\n /** @type {Set<() => void>} */\n #onDispose = new Set()\n\n /** @param {GeometryOptions} options */\n constructor(options) {\n checkOptions('Geometry', options, OPTIONS)\n if (!options?.positions) fail('Geometry', \"'positions' is required - an array of x, y, z per vertex\")\n this.positions = toFloat32('positions', options.positions, 3)\n const n = this.vertexCount\n if (options.normals) this.#normals = toFloat32('normals', options.normals, 3, n)\n if (options.uvs) this.uvs = toFloat32('uvs', options.uvs, 2, n)\n if (options.uvs2) this.uvs2 = toFloat32('uvs2', options.uvs2, 2, n)\n if (options.colors) this.colors = toFloat32('colors', options.colors, 3, n)\n for (const name of POINT_ARRAYS) if (options[name]) this[name] = toFloat32(name, options[name], 1, n)\n if (options.indices) {\n // -1: no indices at all refer to no vertex, so an empty geometry can say so\n let max = -1\n for (let i = 0; i < options.indices.length; i++) {\n const v = options.indices[i]\n if (!Number.isInteger(v) || v < 0) fail('Geometry', `'indices' must be whole numbers 0 or more, found ${describe(v)} at ${i}`)\n if (v > max) max = v\n }\n if (max >= n) fail('Geometry', `'indices' refers to vertex ${max} but there are only ${n} vertices`)\n this.indices = n > 65535 ? Uint32Array.from(options.indices) : Uint16Array.from(options.indices)\n }\n }\n\n /**\n * xyz per vertex. Computed (smooth) from the triangles on first read when not supplied, so\n * points and lines - whose geometry has no triangles - never pay for them - and computed again after\n * needsUpdate(), so they follow positions edited in place. Normals that were supplied, assigned or\n * made by calling computeNormals() are kept as they are.\n * @type {Float32Array}\n */\n get normals() {\n if (!this.#normals) {\n this.computeNormals()\n this.#autoNormals = true\n }\n return /** @type {Float32Array} */ (this.#normals)\n }\n\n set normals(v) {\n this.#normals = v\n this.#autoNormals = false\n }\n\n /** True once normals exist, supplied or computed. */\n get hasNormals() {\n return this.#normals !== null\n }\n\n /** @returns {number} */\n get vertexCount() {\n return this.positions.length / 3\n }\n\n /** Number of indices if indexed, otherwise vertices. @returns {number} */\n get elementCount() {\n return this.indices ? this.indices.length : this.vertexCount\n }\n\n /** The elements actually drawn: elementCount, limited by drawCount. @returns {number} */\n get drawnCount() {\n return this.drawCount === null ? this.elementCount : Math.max(0, Math.min(this.drawCount, this.elementCount))\n }\n\n /**\n * The vertices actually drawn as points: vertexCount, limited by drawCount. Points draw each vertex\n * once and ignore the index, so a mesh's indexed geometry can be shown as its vertices too.\n * @returns {number}\n */\n get drawnVertices() {\n return this.drawCount === null ? this.vertexCount : Math.max(0, Math.min(this.drawCount, this.vertexCount))\n }\n\n /** Local space bounds, cached until needsUpdate(). @returns {Box3} */\n get bounds() {\n return this.#bounds ??= new Box3().expandByPositions(this.positions)\n }\n\n /**\n * Call after editing the arrays in place. It is no longer what its generator made, so toJSON() saves\n * the arrays; normals that were worked out on first read are worked out again on the next.\n * @returns {this}\n */\n needsUpdate() {\n this.source = null\n if (this.#autoNormals) this.#normals = null\n return this.#changed()\n }\n\n #changed() {\n this.version++\n this.#bounds = null\n return this\n }\n\n /**\n * Compute vertex normals from the triangles. Smooth normals average the faces sharing each vertex;\n * flat normals give every face its own vertices (a faceted look), so indexed geometry becomes\n * non-indexed. Non-indexed geometry is assumed to already have its own vertices per triangle.\n * @param {{ flat?: boolean }} [options]\n * @returns {this}\n */\n computeNormals({ flat = false } = {}) {\n if (flat && this.indices) this.#unweld()\n const p = this.positions\n const normals = new Float32Array(p.length)\n const triangles = this.elementCount - (this.elementCount % 3)\n for (let t = 0; t < triangles; t += 3) {\n const a = this.#index(t), b = this.#index(t + 1), c = this.#index(t + 2)\n // face normal (b - a) x (c - a), unnormalised so larger faces weigh more\n const abx = p[b * 3] - p[a * 3], aby = p[b * 3 + 1] - p[a * 3 + 1], abz = p[b * 3 + 2] - p[a * 3 + 2]\n const acx = p[c * 3] - p[a * 3], acy = p[c * 3 + 1] - p[a * 3 + 1], acz = p[c * 3 + 2] - p[a * 3 + 2]\n const nx = aby * acz - abz * acy, ny = abz * acx - abx * acz, nz = abx * acy - aby * acx\n for (const v of [a, b, c]) {\n normals[v * 3] += nx\n normals[v * 3 + 1] += ny\n normals[v * 3 + 2] += nz\n }\n }\n for (let i = 0; i < normals.length; i += 3) {\n const len = Math.hypot(normals[i], normals[i + 1], normals[i + 2])\n if (len > 0) {\n normals[i] /= len\n normals[i + 1] /= len\n normals[i + 2] /= len\n }\n }\n this.normals = normals\n // normals follow from the positions, which a generator would make again: it is still its shape\n return this.#changed()\n }\n\n /** A copy with its own arrays. @returns {Geometry} */\n clone() {\n const g = new Geometry({\n positions: this.positions,\n normals: this.#normals ?? undefined,\n uvs: this.uvs ?? undefined,\n uvs2: this.uvs2 ?? undefined,\n colors: this.colors ?? undefined,\n sizes: this.sizes ?? undefined,\n opacities: this.opacities ?? undefined,\n angles: this.angles ?? undefined,\n indices: this.indices ?? undefined,\n })\n g.source = this.source && { ...this.source }\n g.drawCount = this.drawCount\n return g\n }\n\n /** Release GPU resources made from this geometry. It can still be used; it is re-uploaded on next render. */\n dispose() {\n for (const fn of this.#onDispose) fn()\n }\n\n /** @internal For renderers: called when dispose() is. Returns an unsubscribe function. @param {() => void} fn */\n onDispose(fn) {\n this.#onDispose.add(fn)\n return () => this.#onDispose.delete(fn)\n }\n\n /** A generator description when made by one, otherwise the raw arrays. */\n toJSON() {\n if (this.source) return { ...this.source }\n /** @type {Record<string, number[]>} */\n const json = { positions: Array.from(this.positions) }\n if (this.#normals) json.normals = Array.from(this.#normals)\n if (this.uvs) json.uvs = Array.from(this.uvs)\n if (this.uvs2) json.uvs2 = Array.from(this.uvs2)\n if (this.colors) json.colors = Array.from(this.colors)\n for (const name of POINT_ARRAYS) if (this[name]) json[name] = Array.from(/** @type {Float32Array} */ (this[name]))\n if (this.indices) json.indices = Array.from(this.indices)\n return json\n }\n\n /** @param {number} i */\n #index(i) {\n return this.indices ? this.indices[i] : i\n }\n\n // Expand indexed vertices so no two triangles share one.\n #unweld() {\n const idx = /** @type {Uint16Array | Uint32Array} */ (this.indices)\n const expand = (src, size) => {\n if (!src) return null\n const out = new Float32Array(idx.length * size)\n for (let i = 0; i < idx.length; i++) {\n for (let k = 0; k < size; k++) out[i * size + k] = src[idx[i] * size + k]\n }\n return out\n }\n this.positions = /** @type {Float32Array} */ (expand(this.positions, 3))\n this.uvs = expand(this.uvs, 2)\n this.uvs2 = expand(this.uvs2, 2)\n this.colors = expand(this.colors, 3)\n for (const name of POINT_ARRAYS) this[name] = expand(this[name], 1)\n this.indices = null\n this.source = null\n }\n}\n\n/**\n * @param {string} name @param {ArrayLike<number>} values @param {number} size per vertex\n * @param {number} [count] expected vertex count\n * @returns {Float32Array}\n */\nfunction toFloat32(name, values, size, count) {\n if (!values || typeof values !== 'object' || typeof values.length !== 'number') {\n fail('Geometry', `'${name}' must be an array of numbers, got ${describe(values)}`)\n }\n if (values.length % size !== 0) fail('Geometry', `'${name}' has ${values.length} numbers - expected ${size} per vertex`)\n if (count !== undefined && values.length !== count * size) {\n fail('Geometry', `'${name}' has ${values.length / size} entries but 'positions' has ${count} vertices`)\n }\n const out = Float32Array.from(values)\n for (let i = 0; i < out.length; i++) {\n if (Number.isNaN(out[i])) fail('Geometry', `'${name}' contains a non-number at index ${i}`)\n }\n return out\n}\n","import { checkNumber, checkOneOf, checkOptions, describe, fail } from '../validate.js'\n\n/**\n * Raw pixels, RGBA, top row first: bytes for ordinary images, floats for HDR (linear radiance).\n * @typedef {{ data: Uint8Array | Float32Array, width: number, height: number }} DataImage\n */\n/** @typedef {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap | OffscreenCanvas | DataImage} TextureImage */\n\n/**\n * @typedef {object} TextureOptions\n * @property {TextureImage} [image] the pixels; omit and give a url to load them\n * @property {string} [url] image to load (starts loading immediately in a browser); a .hdr file loads as\n * linear HDR radiance, for scene.environment; a video (.mp4, .webm, .ogv, .mov, .m4v) plays muted and on a\n * loop, and texture.image is its <video> to pause, seek or unmute\n * @property {'srgb' | 'linear'} [colorSpace] 'srgb' for colour maps (default), 'linear' for data\n * maps such as normal and roughness maps\n * @property {'repeat' | 'clamp' | 'mirror'} [wrap] (default 'repeat')\n * @property {number[]} [repeat] [u, v] (default [1, 1])\n * @property {number[]} [offset] [u, v] (default [0, 0])\n * @property {number} [rotation] turns the image on the surface, in radians, about `center` (default 0)\n * @property {number[]} [center] [u, v] the point rotation turns about, in repeated UVs (default [0, 0], the\n * corner, as glTF has it; [0.5, 0.5] for the middle of an unrepeated image)\n * @property {0 | 1} [uvSet] which UV set to read: 0 the first, 1 the second (Geometry uvs2) - baked occlusion\n * and light maps usually come on the second (default 0)\n * @property {'linear' | 'nearest'} [filter] (default 'linear')\n * @property {boolean} [mipmaps] (default true; false for a video, which would make them every frame)\n * @property {number} [anisotropy] samples along a surface seen at a glancing angle - floors and roads\n * stay sharp into the distance. Up to what the GPU allows; 1 is off (default 8)\n * @property {boolean} [flipY] flip on upload; false for glTF-style UVs (default false)\n */\n\nconst OPTIONS = ['image', 'url', 'colorSpace', 'wrap', 'repeat', 'offset', 'rotation', 'center', 'uvSet', 'filter', 'mipmaps', 'anisotropy', 'flipY']\nconst DEFAULTS = { colorSpace: 'srgb', wrap: 'repeat', repeat: [1, 1], offset: [0, 0], rotation: 0, center: [0, 0], uvSet: 0, filter: 'linear',\n mipmaps: true, anisotropy: 8, flipY: false }\n\nconst HINTS = {\n src: \"use 'url' for the image address\",\n encoding: \"use colorSpace: 'srgb' | 'linear'\",\n wrapS: \"use wrap: 'repeat' | 'clamp' | 'mirror' (applies to both directions)\",\n maxAnisotropy: \"use 'anisotropy' - samples along glancing angles, 1 for off\",\n channel: \"use 'uvSet' - 0 for the first UV set, 1 for the second\",\n texCoord: \"use 'uvSet' - 0 for the first UV set, 1 for the second\",\n scale: \"use 'repeat' - [u, v] times across\",\n}\n\n/**\n * Part of an image, in its pixels from the top left, as needsUpdate() takes it.\n * @typedef {{ x: number, y: number, width: number, height: number }} TextureRegion\n */\n\n// how many updates a texture remembers the region of, for a renderer catching up on several - a\n// frame of paint can make a hundred or so\nconst CHANGES_KEPT = 256\n\n/**\n * An image for a material map. A video's frames upload by themselves as it plays; after drawing on\n * a canvas, call `needsUpdate()` - with the rectangle drawn in, to send only that.\n */\nexport class Texture {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n /** @type {TextureImage | null} */\n #image = null\n /** @type {string | null} */\n url = null\n /** @type {'srgb' | 'linear'} */\n #colorSpace = 'srgb'\n /** set by the app, rather than left to its default - a material's data slot leaves it alone then */\n #colorSpaceSet = false\n /** @type {'repeat' | 'clamp' | 'mirror'} */\n wrap = 'repeat'\n repeat = [1, 1]\n offset = [0, 0]\n /** Turns the image on the surface, in radians, about `center`. */\n rotation = 0\n /** [u, v] the point rotation turns about, in repeated UVs. */\n center = [0, 0]\n /** Which UV set it reads: 0 the first, 1 the second (Geometry uvs2). @type {0 | 1} */\n uvSet = 0\n /** @type {'linear' | 'nearest'} */\n filter = 'linear'\n mipmaps = true\n /** Samples along glancing angles, up to the GPU's limit; 1 is off. Call needsUpdate() after changing it. */\n anisotropy = 8\n flipY = false\n /** @internal Bumped by needsUpdate() so renderers re-upload. */\n version = 0\n /** What each recent update changed - its region, or null for all of it. @type {{ version: number, region: TextureRegion | null }[]} */\n #changes = []\n /** Resolves when the image is available (immediately when one was given). @type {Promise<Texture>} */\n ready\n\n /** @type {Set<() => void>} */\n #onDispose = new Set()\n\n /** @param {TextureOptions | string} [options] options, or just a url */\n constructor(options = {}) {\n if (typeof options === 'string') options = { url: options }\n checkOptions('Texture', options, OPTIONS, HINTS)\n const o = { ...DEFAULTS, ...options }\n this.#colorSpace = checkOneOf('Texture', 'colorSpace', o.colorSpace, ['srgb', 'linear'])\n this.#colorSpaceSet = options.colorSpace !== undefined\n this.wrap = checkOneOf('Texture', 'wrap', o.wrap, ['repeat', 'clamp', 'mirror'])\n this.filter = checkOneOf('Texture', 'filter', o.filter, ['linear', 'nearest'])\n this.repeat = pair('repeat', o.repeat)\n this.offset = pair('offset', o.offset)\n this.rotation = checkNumber('Texture', 'rotation', o.rotation)\n this.center = pair('center', o.center)\n if (o.uvSet !== 0 && o.uvSet !== 1) fail('Texture', `'uvSet' is 0 (the first UV set) or 1 (the second), got ${describe(o.uvSet)}`)\n this.uvSet = o.uvSet\n // a video would make mipmaps every frame: off unless asked for\n this.mipmaps = options.mipmaps !== undefined ? !!options.mipmaps : !(isVideo(o.image) || (!o.image && VIDEO.test(o.url ?? '')))\n this.anisotropy = checkNumber('Texture', 'anisotropy', o.anisotropy)\n if (!(this.anisotropy >= 1)) fail('Texture', `'anisotropy' is how many samples along a glancing angle - 1 (off) or more, got ${this.anisotropy}`)\n this.flipY = !!o.flipY\n this.url = o.url ?? null\n\n if (o.image) {\n this.image = o.image\n this.ready = isVideo(o.image) ? loaded(/** @type {HTMLVideoElement} */ (o.image)).then(() => this) : Promise.resolve(this)\n this.ready.catch(() => {})\n } else if (this.url) {\n this.ready = this.#load(this.url)\n // a failed load is reported by whoever awaits `ready`; don't also raise an unhandled rejection\n this.ready.catch(() => {})\n } else {\n fail('Texture', \"needs an 'image' or a 'url'\")\n }\n }\n\n /** Call after redrawing a canvas or advancing a video. @returns {this} */\n /**\n * The pixels: null until loaded. A <video>'s frames upload by themselves while it plays.\n * @returns {TextureImage | null}\n */\n get image() { return this.#image }\n /** @param {TextureImage | null} v */\n set image(v) {\n this.#image = v\n this.needsUpdate()\n if (isVideo(v)) this.#follow(/** @type {HTMLVideoElement} */ (v))\n }\n\n // Each new frame of a playing video marks the texture changed, so views redraw with it: the\n // browser's own per-frame callback where there is one, otherwise a check every animation frame\n // while it plays. Following stops when the image is replaced.\n /** @param {HTMLVideoElement} video */\n #follow(video) {\n if (typeof video.requestVideoFrameCallback === 'function') {\n const frame = () => {\n if (this.#image !== video) return\n this.needsUpdate()\n video.requestVideoFrameCallback(frame)\n }\n video.requestVideoFrameCallback(frame)\n return\n }\n let last = -1, running = false\n const tick = () => {\n if (this.#image !== video || video.paused || video.ended) {\n running = false\n return\n }\n if (video.currentTime !== last) {\n last = video.currentTime\n this.needsUpdate()\n }\n requestAnimationFrame(tick)\n }\n const start = () => {\n if (running || this.#image !== video) return\n running = true\n requestAnimationFrame(tick)\n }\n video.addEventListener('play', start)\n // a seek while paused shows a new frame too\n video.addEventListener('seeked', () => {\n if (this.#image === video) this.needsUpdate()\n })\n if (!video.paused) start()\n }\n\n /** 'srgb' for colour (decoded to linear by the GPU), 'linear' for data such as normals and roughness. Call needsUpdate() after changing it. @returns {'srgb' | 'linear'} */\n get colorSpace() { return this.#colorSpace }\n set colorSpace(v) {\n this.#colorSpace = checkOneOf('Texture', 'colorSpace', v, ['srgb', 'linear'])\n this.#colorSpaceSet = true\n }\n\n /** @internal Whether the app chose the colour space, rather than leaving the default. @returns {boolean} */\n get colorSpaceSet() { return this.#colorSpaceSet }\n\n /**\n * Upload the image again, after drawing on it (a canvas) or changing its pixels. Give the\n * rectangle that changed - in the image's pixels, from its top left - and only that is sent: for a\n * big canvas drawn on a little at a time, far less to send each frame.\n *\n * ctx.fillRect(x, y, 20, 20)\n * texture.needsUpdate({ x, y, width: 20, height: 20 })\n * @param {TextureRegion} [region]\n * @returns {this}\n */\n needsUpdate(region) {\n /** @type {TextureRegion | null} */\n let changed = null\n if (region !== undefined) {\n const { x, y, width, height } = region ?? /** @type {any} */ ({})\n if (![x, y, width, height].every((v) => typeof v === 'number' && Number.isFinite(v)) || width < 0 || height < 0) {\n fail('Texture', `needsUpdate() takes the region changed, { x, y, width, height } in the image's pixels, got ${describe(region)}`)\n }\n // whole pixels, covering every one the region touches\n const x0 = Math.floor(x), y0 = Math.floor(y)\n changed = { x: x0, y: y0, width: Math.ceil(x + width) - x0, height: Math.ceil(y + height) - y0 }\n }\n this.version++\n this.#changes.push({ version: this.version, region: changed })\n if (this.#changes.length > CHANGES_KEPT) this.#changes.shift()\n return this\n }\n\n /**\n * @internal What changed since a version a renderer uploaded: each update's region since, or null\n * when that's all of it - an update without a region, or one too long ago to know.\n * @param {number} version\n * @returns {TextureRegion[] | null}\n */\n changedSince(version) {\n const first = this.#changes[0]\n if (!first || first.version > version + 1) return null\n /** @type {TextureRegion[]} */\n const regions = []\n for (const { version: v, region } of this.#changes) {\n if (v <= version) continue\n if (!region) return null\n regions.push(region)\n }\n return regions.length ? regions : null\n }\n\n /** Release the GPU copy. @returns {void} */\n dispose() {\n for (const fn of this.#onDispose) fn()\n }\n\n /** @internal For renderers. Returns an unsubscribe function. @param {() => void} fn */\n onDispose(fn) {\n this.#onDispose.add(fn)\n return () => this.#onDispose.delete(fn)\n }\n\n /** A description (url plus options that differ from the defaults), or null for an in-memory image. */\n toJSON() {\n if (!this.url) return null\n /** @type {Record<string, unknown>} */\n const json = { url: this.url }\n for (const [key, value] of Object.entries(DEFAULTS)) {\n const current = this[/** @type {keyof typeof DEFAULTS} */ (key)]\n if (JSON.stringify(current) !== JSON.stringify(value)) json[key] = current\n }\n return json\n }\n\n /** HDR radiance rather than display colours - floats, tone mapped when drawn. @returns {boolean} */\n get isHDR() {\n return !!this.image && 'data' in this.image && this.image.data instanceof Float32Array\n }\n\n /** @param {string} url @returns {Promise<Texture>} */\n async #load(url) {\n if (VIDEO.test(url)) {\n if (typeof document === 'undefined') throw new Error(`Texture: can't load '${url}' - no video support in this environment`)\n const video = document.createElement('video')\n // muted, so browsers let it play by itself; inline, so phones don't take it full screen\n Object.assign(video, { crossOrigin: 'anonymous', muted: true, loop: true, playsInline: true, autoplay: true, src: url })\n try {\n await loaded(video)\n } catch {\n throw new Error(`Texture: failed to load '${url}'`)\n }\n // a browser that won't autoplay leaves it paused on its first frame: video.play() on a click starts it\n video.play()?.catch(() => {})\n this.image = video\n return this\n }\n if (/\\.hdr($|[?#])/i.test(url)) {\n const [{ parseHDR }, response] = await Promise.all([import('../hdr.js'), fetch(url)])\n if (!response.ok) throw new Error(`Texture: failed to load '${url}' (${response.status})`)\n this.image = parseHDR(await response.arrayBuffer())\n this.colorSpace = 'linear'\n return this\n }\n if (typeof Image === 'undefined') {\n throw new Error(`Texture: can't load '${url}' - no Image support in this environment`)\n }\n const img = new Image()\n img.crossOrigin = 'anonymous'\n img.src = url\n try {\n await img.decode()\n } catch {\n throw new Error(`Texture: failed to load '${url}'`)\n }\n this.image = img\n return this\n }\n}\n\nconst VIDEO = /\\.(mp4|webm|ogv|mov|m4v)($|[?#])/i\n\n/** @internal A <video>, whose frames change as it plays. @param {unknown} image @returns {boolean} */\nexport function isVideo(image) {\n return typeof HTMLVideoElement !== 'undefined' && image instanceof HTMLVideoElement\n}\n\n/** Resolves once a video has a frame to show. @param {HTMLVideoElement} video @returns {Promise<void>} */\nfunction loaded(video) {\n if (video.readyState >= 2) return Promise.resolve()\n return new Promise((resolve, reject) => {\n video.addEventListener('loadeddata', () => resolve(), { once: true })\n video.addEventListener('error', () => reject(new Error('Texture: the video failed to load')), { once: true })\n })\n}\n\n/**\n * Load an image as a texture; resolves once it has decoded.\n * @param {string} url\n * @param {Omit<TextureOptions, 'url' | 'image'>} [options]\n * @returns {Promise<Texture>}\n */\nexport function loadTexture(url, options = {}) {\n return new Texture({ ...options, url }).ready\n}\n\n/** @param {string} name @param {unknown} v @returns {number[]} */\nfunction pair(name, v) {\n if (!Array.isArray(v) || v.length !== 2 || v.some((n) => typeof n !== 'number')) {\n fail('Texture', `'${name}' must be [u, v], got ${describe(v)}`)\n }\n return [v[0], v[1]]\n}\n","import { Color } from '../value/Color.js'\nimport { checkNumber, checkOneOf, checkOptions, describe, fail, warnOnce } from '../validate.js'\nimport { Texture } from './Texture.js'\n\n/** @import { ColorInput } from '../types.js' */\n/** @import { TextureOptions } from './Texture.js' */\n\n/** A map: a Texture, its options, or just a url. @typedef {Texture | TextureOptions | string} MapInput */\n\n/**\n * @typedef {object} MaterialOptions\n * @property {string} [name]\n * @property {ColorInput} [color] base colour (default white)\n * @property {MapInput | null} [map] colour texture\n * @property {number} [opacity] 0-1; below 1 renders in the transparent pass (default 1)\n * @property {boolean} [transparent] blend at any opacity - for maps with soft alpha edges (default: opacity below 1)\n * @property {number} [alphaTest] 0-1: drop pixels whose alpha is below it - cut-outs such as leaves (default 0)\n * @property {number} [roughness] 0 = mirror, 1 = matte (default 0.5)\n * @property {number} [metalness] 0-1 (default 0)\n * @property {MapInput | null} [roughnessMap] multiplies roughness by its green channel (glTF)\n * @property {MapInput | null} [metalnessMap] multiplies metalness by its blue channel (glTF)\n * @property {MapInput | null} [normalMap] tangent-space normals, +Y up (glTF/OpenGL convention)\n * @property {number} [normalScale] strength of the normal map (default 1)\n * @property {MapInput | null} [bumpMap] heights in its red channel, shown as bumps - for height textures and ones\n * drawn in code, with no need to make a normal map\n * @property {number} [bumpScale] how high a height of 1 stands, in the mesh's own units (default 1)\n * @property {number} [triplanar] project the maps onto the mesh from its three axes instead of using UVs -\n * for scans and CAD models, which have none. The number is how many times a map repeats per unit of the\n * mesh's own space; the maps stay on the mesh as it moves. 0 (the default) uses the UVs\n * @property {MapInput | null} [aoMap] ambient occlusion in its red channel; darkens environment and ambient light\n * @property {number} [aoMapIntensity] 0-1 (default 1)\n * @property {MapInput | null} [emissiveMap] multiplies the emissive colour\n * @property {MapInput | null} [lightMap] light baked into a texture, added as light from all round - usually on\n * the second UV set (uvSet: 1)\n * @property {number} [lightMapIntensity] (default 1)\n * @property {number} [environmentIntensity] this material's share of the environment's light and reflections:\n * lower for a matte floor in a shiny showroom, higher to make one thing catch the light (default 1)\n * @property {ColorInput} [emissive] glow colour (default black)\n * @property {number} [emissiveIntensity] (default 1)\n * @property {number} [transmission] 0-1: how much light passes through, as through glass (default 0). Unlike\n * opacity, which fades the whole surface, glass keeps its reflections, and shows less of what is behind it\n * towards its edges. Its colour shows in proportion to 1 - transmission\n * @property {number} [clearcoat] 0-1: a clear glossy layer over the surface - car paint, lacquer, varnish (default 0)\n * @property {number} [clearcoatRoughness] 0-1: how glossy the coat is, 0 a mirror (default 0)\n * @property {number} [sheen] 0-1: the soft bright rim of cloth at grazing angles - velvet, felt, upholstery (default 0)\n * @property {ColorInput} [sheenColor] the sheen's colour (default white)\n * @property {number} [sheenRoughness] 0-1: a thin bright rim at 0, a broad soft glow at 1 (default 0.5)\n * @property {number} [ior] index of refraction, 1 or more: how strongly a non-metal reflects - water 1.33, glass and\n * plastic 1.5 (the default), diamond 2.4\n * @property {number} [specularIntensity] 0-1: scales a non-metal's reflections, 0 for none - chalk, clay (default 1)\n * @property {ColorInput} [specularColor] tints a non-metal's reflections face on (default white)\n * @property {number} [anisotropy] 0-1: brushed metal - highlights drawn out along the brushing, which runs along\n * the UVs' u (around the mesh where it has no UVs) (default 0)\n * @property {number} [anisotropyRotation] turns the brushing from the UVs' u, in radians (default 0)\n * @property {number} [translucency] 0-1: light through thin surfaces, lighting them from behind - leaves, paper,\n * lampshades, curtains (default 0)\n * @property {ColorInput} [translucencyColor] tints the light that comes through (default white)\n * @property {MapInput | null} [matcap] a picture of a lit sphere that gives the whole look - clay, wax, chrome,\n * a painted ball - picked by which way the surface faces the camera. Lights, shadows and the environment are\n * ignored; the colour and colour map multiply it\n * @property {number} [toon] cartoon shading in this many flat tones (2 or more) with a hard-edged highlight;\n * 0 (the default) is smooth\n * @property {boolean} [unlit] flat colour that ignores lights (default false)\n * @property {boolean} [flatShading] faceted look from face normals (default false)\n * @property {boolean} [doubleSided] draw back faces too (default false)\n * @property {boolean} [vertexColors] multiply by the geometry's colors (default false)\n * @property {boolean} [fog] fade into the scene's fog with distance (default true) - false for a sky or a far backdrop\n * @property {'normal' | 'additive' | 'multiply'} [blending] how it combines with what is behind it: 'additive' adds\n * light (glows, sparks), 'multiply' darkens it as a filter does - cyan over magenta is blue (default 'normal')\n * @property {boolean} [depthWrite] (default true)\n * @property {boolean} [depthTest] (default true)\n * @property {number} [size] Points: diameter in world units, or pixels when sizeAttenuation is off (default 1)\n * @property {boolean} [sizeAttenuation] Points: sized in the world, so smaller with distance (default true)\n * @property {number} [width] Lines: width in pixels (default 1)\n * @property {number} [dash] Lines: dashed, with dashes this long in the model's units; 0 is solid (default 0)\n * @property {number} [gap] Lines: the gaps between dashes; 0 is as long as the dashes (default 0)\n * @property {number} [dashOffset] Lines: moves the dashes along the lines - animate it for flow (default 0)\n */\n\n// the matcap last: the first map's repeat and offset are every map's, and a matcap has none\nconst MAPS = ['map', 'roughnessMap', 'metalnessMap', 'normalMap', 'bumpMap', 'aoMap', 'emissiveMap', 'lightMap', 'matcap']\n// data maps hold numbers, not colours\nconst LINEAR_MAPS = new Set(['roughnessMap', 'metalnessMap', 'normalMap', 'bumpMap', 'aoMap'])\nconst FLAGS = ['unlit', 'flatShading', 'doubleSided', 'vertexColors', 'depthWrite', 'depthTest', 'sizeAttenuation', 'transparent', 'fog']\nconst NUMBERS = { opacity: [0, 1], roughness: [0, 1], metalness: [0, 1], emissiveIntensity: [0, Infinity], size: [0, Infinity], width: [0, Infinity],\n alphaTest: [0, 1], normalScale: [-Infinity, Infinity], aoMapIntensity: [0, 1], triplanar: [0, Infinity], bumpScale: [-Infinity, Infinity],\n transmission: [0, 1], clearcoat: [0, 1], clearcoatRoughness: [0, 1], sheen: [0, 1], sheenRoughness: [0, 1], ior: [1, Infinity],\n specularIntensity: [0, 1], anisotropy: [0, 1], anisotropyRotation: [-Infinity, Infinity], translucency: [0, 1], toon: [0, 16],\n lightMapIntensity: [0, Infinity], environmentIntensity: [0, Infinity], dash: [0, Infinity], gap: [0, Infinity],\n dashOffset: [-Infinity, Infinity] }\n// colours, and their defaults\nconst COLORS = { color: 0xffffff, emissive: 0x000000, sheenColor: 0xffffff, specularColor: 0xffffff, translucencyColor: 0xffffff }\nconst DEFAULTS = {\n name: '', opacity: 1, alphaTest: 0, roughness: 0.5, metalness: 0, normalScale: 1, bumpScale: 1, aoMapIntensity: 1, triplanar: 0, emissiveIntensity: 1,\n transmission: 0, clearcoat: 0, clearcoatRoughness: 0, sheen: 0, sheenRoughness: 0.5, ior: 1.5, specularIntensity: 1, anisotropy: 0,\n anisotropyRotation: 0, translucency: 0, toon: 0, lightMapIntensity: 1, environmentIntensity: 1, unlit: false, flatShading: false,\n doubleSided: false, vertexColors: false, blending: 'normal', depthWrite: true, depthTest: true, fog: true,\n size: 1, sizeAttenuation: true, width: 1, dash: 0, gap: 0, dashOffset: 0,\n}\nconst OPTIONS = ['name', ...Object.keys(COLORS), ...MAPS, ...FLAGS, ...Object.keys(NUMBERS), 'blending']\n\n// what agents (and three.js habits) will reach for\nconst HINTS = {\n type: \"phoria2 has one material - drop 'type' and set 'unlit: true' for a flat colour\",\n side: \"use 'doubleSided: true'\",\n wireframe: 'use new Lines({ geometry: edges(geometry) }) for a wireframe',\n shininess: \"use 'roughness' (0 = mirror, 1 = matte)\",\n envMapIntensity: \"use 'environmentIntensity'\",\n reflectivityScale: \"use 'environmentIntensity'\",\n matcapMap: \"use 'matcap'\",\n gradientMap: \"use 'toon' - the number of flat tones\",\n cel: \"use 'toon' - the number of flat tones\",\n celShading: \"use 'toon' - the number of flat tones\",\n specular: \"use 'specularIntensity' and 'specularColor' for a non-metal's reflections, or 'roughness' and 'metalness'\",\n reflectivity: \"use 'ior' (1.5 by default) or 'specularIntensity'\",\n anisotropyStrength: \"use 'anisotropy'\",\n diffuseTransmission: \"use 'translucency'\",\n subsurface: \"use 'translucency' for light through thin surfaces\",\n colour: \"use 'color'\",\n emissiveColor: \"use 'emissive'\",\n alpha: \"use 'opacity'\",\n}\n\n/**\n * The one material: what a surface looks like. Plain objects passed as a `material` become\n * Materials; construct one to share it between nodes. The renderer compiles a shader variant\n * from what is actually used, so an unlit colour costs no lighting maths.\n */\nexport class Material {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n // values from DEFAULTS, in the constructor - one list, which toJSON leaves out\n /** @type {string} */ name\n /** @type {number} */ opacity\n /** Drop pixels with less alpha than this - hard-edged cut-outs, drawn with the opaque pass. @type {number} */ alphaTest\n /** @type {number} */ normalScale\n /** How high a bump map's height of 1 stands, in the mesh's own units. @type {number} */ bumpScale\n /** @type {number} */ aoMapIntensity\n /** Maps projected from the mesh's three axes, this many repeats per unit; 0 uses the UVs. @type {number} */ triplanar\n /** @type {number} */ roughness\n /** @type {number} */ metalness\n /** @type {number} */ emissiveIntensity\n /** How much light passes through, as through glass: 0-1. @type {number} */ transmission\n /** A clear glossy layer over the surface: 0-1. @type {number} */ clearcoat\n /** How glossy the coat is, 0 a mirror. @type {number} */ clearcoatRoughness\n /** The soft bright rim of cloth: 0-1. @type {number} */ sheen\n /** A thin bright rim at 0, a broad soft glow at 1. @type {number} */ sheenRoughness\n /** Index of refraction: how strongly a non-metal reflects (1.5). @type {number} */ ior\n /** Scales a non-metal's reflections, 0-1. @type {number} */ specularIntensity\n /** Brushed metal: 0-1. @type {number} */ anisotropy\n /** Turns the brushing from the UVs' u, in radians. @type {number} */ anisotropyRotation\n /** Light through thin surfaces: 0-1. @type {number} */ translucency\n /** Cartoon shading in this many flat tones; 0 is smooth. @type {number} */ toon\n /** @type {number} */ lightMapIntensity\n /** This material's share of the environment's light and reflections. @type {number} */ environmentIntensity\n /** @type {boolean} */ unlit\n /** @type {boolean} */ flatShading\n /** @type {boolean} */ doubleSided\n /** @type {boolean} */ vertexColors\n /** Fades into the scene's fog with distance. @type {boolean} */ fog\n /** @type {'normal' | 'additive' | 'multiply'} */ blending\n /** @type {boolean} */ depthWrite\n /** @type {boolean} */ depthTest\n /** @type {number} */ size\n /** @type {boolean} */ sizeAttenuation\n /** @type {number} */ width\n /** Lines: dash length in the model's units; 0 is solid. @type {number} */ dash\n /** Lines: gap length; 0 is the dash's. @type {number} */ gap\n /** Lines: how far the dashes have moved along. @type {number} */ dashOffset\n\n /** @type {Record<string, Color>} */\n #colors = Object.fromEntries(Object.entries(COLORS).map(([key, hex]) => [key, new Color(hex)]))\n #transparent = false\n /** @type {Record<string, Texture | null>} */\n #maps = Object.fromEntries(MAPS.map((m) => [m, null]))\n /** @type {Set<() => void>} */\n #onDispose = new Set()\n\n /** @param {MaterialOptions} [options] */\n constructor(options = {}) {\n checkOptions('Material', options, OPTIONS, HINTS)\n Object.assign(this, DEFAULTS)\n for (const [key, value] of /** @type {[string, any][]} */ (Object.entries(options))) {\n if (value === undefined) continue\n if (key in COLORS) this.#colors[key].set(value, 'Material')\n else if (MAPS.includes(key)) this.setMap(key, value)\n else if (FLAGS.includes(key)) this[key] = bool(key, value)\n else if (key in NUMBERS) this[key] = range(key, value, NUMBERS[key])\n else if (key === 'blending') this.blending = checkOneOf('Material', 'blending', value, ['normal', 'additive', 'multiply'])\n else if (key === 'name') this.name = String(value)\n }\n }\n\n /** @internal\n * A Material from a Material (returned as is) or options.\n * @param {Material | MaterialOptions} input\n * @returns {Material}\n */\n static fromInput(input) {\n if (input instanceof Material) return input\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n fail('Material', `expected material options such as { color: 'orange' }, got ${describe(input)}`)\n }\n return new Material(input)\n }\n\n /** Base colour; assign any colour input. @returns {Color} */\n get color() { return this.#colors.color }\n /** @param {ColorInput} v */\n set color(v) { this.#colors.color.set(v, 'Material') }\n\n /** Glow colour; assign any colour input. @returns {Color} */\n get emissive() { return this.#colors.emissive }\n /** @param {ColorInput} v */\n set emissive(v) { this.#colors.emissive.set(v, 'Material') }\n\n /** The sheen's colour; assign any colour input. @returns {Color} */\n get sheenColor() { return this.#colors.sheenColor }\n /** @param {ColorInput} v */\n set sheenColor(v) { this.#colors.sheenColor.set(v, 'Material') }\n\n /** Tints a non-metal's reflections face on; assign any colour input. @returns {Color} */\n get specularColor() { return this.#colors.specularColor }\n /** @param {ColorInput} v */\n set specularColor(v) { this.#colors.specularColor.set(v, 'Material') }\n\n /** Tints the light that comes through a translucent surface; assign any colour input. @returns {Color} */\n get translucencyColor() { return this.#colors.translucencyColor }\n /** @param {ColorInput} v */\n set translucencyColor(v) { this.#colors.translucencyColor.set(v, 'Material') }\n\n /** @returns {Texture | null} */\n get map() { return this.#maps.map }\n /** @param {MapInput | null} v */\n set map(v) { this.setMap('map', v) }\n /** @returns {Texture | null} */\n get roughnessMap() { return this.#maps.roughnessMap }\n /** @param {MapInput | null} v */\n set roughnessMap(v) { this.setMap('roughnessMap', v) }\n /** @returns {Texture | null} */\n get metalnessMap() { return this.#maps.metalnessMap }\n /** @param {MapInput | null} v */\n set metalnessMap(v) { this.setMap('metalnessMap', v) }\n /** @returns {Texture | null} */\n get normalMap() { return this.#maps.normalMap }\n /** @param {MapInput | null} v */\n set normalMap(v) { this.setMap('normalMap', v) }\n /** @returns {Texture | null} */\n get bumpMap() { return this.#maps.bumpMap }\n /** @param {MapInput | null} v */\n set bumpMap(v) { this.setMap('bumpMap', v) }\n /** @returns {Texture | null} */\n get aoMap() { return this.#maps.aoMap }\n /** @param {MapInput | null} v */\n set aoMap(v) { this.setMap('aoMap', v) }\n /** @returns {Texture | null} */\n get emissiveMap() { return this.#maps.emissiveMap }\n /** @param {MapInput | null} v */\n set emissiveMap(v) { this.setMap('emissiveMap', v) }\n /** Light baked into a texture. @returns {Texture | null} */\n get lightMap() { return this.#maps.lightMap }\n /** @param {MapInput | null} v */\n set lightMap(v) { this.setMap('lightMap', v) }\n /** A picture of a lit sphere that gives the whole look. @returns {Texture | null} */\n get matcap() { return this.#maps.matcap }\n /** @param {MapInput | null} v */\n set matcap(v) { this.setMap('matcap', v) }\n\n /** @internal\n * @param {string} slot one of map, roughnessMap, metalnessMap, normalMap, bumpMap, aoMap, emissiveMap, lightMap, matcap\n * @param {MapInput | null} value\n */\n setMap(slot, value) {\n if (value == null) {\n this.#maps[slot] = null\n return\n }\n if (value instanceof Texture) {\n // a data slot reads its texture as numbers, not colour: one left at the default colour space\n // (loadTexture('n.png'), say) is switched; one set to srgb on purpose is kept, with a word\n if (LINEAR_MAPS.has(slot) && value.colorSpace === 'srgb') {\n if (!value.colorSpaceSet) {\n value.colorSpace = 'linear'\n value.needsUpdate()\n } else warnOnce(value, `'${slot}' holds data, not colour, so its texture should be colorSpace: 'linear' - this one is 'srgb', and will be decoded as colour`)\n }\n this.#maps[slot] = value\n return\n }\n // descriptions and urls take the colour space the slot needs\n const options = typeof value === 'string' ? { url: value } : value\n if (typeof options !== 'object' || Array.isArray(options)) fail('Material', `'${slot}' must be a Texture, a url or texture options, got ${describe(value)}`)\n this.#maps[slot] = new Texture({ colorSpace: LINEAR_MAPS.has(slot) ? 'linear' : 'srgb', ...options })\n }\n\n /** The maps that are set, by slot. @returns {[string, Texture][]} */\n get textures() {\n return /** @type {[string, Texture][]} */ (Object.entries(this.#maps).filter(([, t]) => t))\n }\n\n /** Rendered in the transparent pass: an opacity below 1, additive or multiply blending, or set for maps with soft alpha. @returns {boolean} */\n get transparent() {\n return this.#transparent || this.opacity < 1 || this.transmission > 0 || this.blending !== 'normal'\n }\n /** @param {boolean} v */\n set transparent(v) { this.#transparent = !!v }\n\n /** @internal\n * Which shader features this material needs - renderers compile one program per distinct key.\n * @returns {string}\n */\n get variant() {\n const parts = [this.unlit ? 'unlit' : 'lit']\n for (const [slot] of this.textures) parts.push(slot)\n if (this.alphaTest > 0) parts.push('cutout')\n if (this.transmission > 0) parts.push('glass')\n if (this.clearcoat > 0) parts.push('clearcoat')\n if (this.sheen > 0) parts.push('sheen')\n if (this.anisotropy > 0) parts.push('brushed')\n if (this.translucency > 0) parts.push('translucent')\n if (this.toon > 0) parts.push('toon')\n if (this.flatShading) parts.push('flat')\n if (this.vertexColors) parts.push('vcolor')\n return parts.join('+')\n }\n\n /** Resolves when every texture has loaded. @returns {Promise<void>} */\n async ready() {\n await Promise.all(this.textures.map(([, t]) => t.ready))\n }\n\n /** @returns {Material} */\n clone() {\n const copy = new Material(this.toJSON(true))\n // the colours exactly: a description rounds them to 8-bit sRGB and can't hold values past 1\n for (const [key, c] of Object.entries(this.#colors)) copy.#colors[key].set(c)\n return copy\n }\n\n /** Release GPU resources for this material (programs are shared and kept). */\n dispose() {\n for (const fn of this.#onDispose) fn()\n }\n\n /** @internal For renderers. Returns an unsubscribe function. @param {() => void} fn */\n onDispose(fn) {\n this.#onDispose.add(fn)\n return () => this.#onDispose.delete(fn)\n }\n\n /**\n * Options that differ from the defaults, ready for JSON.\n * @param {boolean} [keepTextures] keep Texture objects instead of their descriptions (for clone)\n * @returns {MaterialOptions}\n */\n toJSON(keepTextures = false) {\n /** @type {Record<string, unknown>} */\n const json = {}\n for (const [key, value] of Object.entries(DEFAULTS)) {\n if (this[key] !== value) json[key] = this[key]\n }\n if (this.#transparent) json.transparent = true\n for (const [key, c] of Object.entries(this.#colors)) if (c.getHex() !== COLORS[key]) json[key] = c.getStyle()\n for (const [slot, t] of this.textures) {\n const desc = keepTextures ? t : t.toJSON()\n if (desc) json[slot] = desc\n }\n return json\n }\n}\n\n/** @param {string} name @param {unknown} v */\nfunction bool(name, v) {\n if (typeof v !== 'boolean') fail('Material', `'${name}' must be true or false, got ${describe(v)}`)\n return v\n}\n\n/** @param {string} name @param {unknown} v @param {number[]} limits */\nfunction range(name, v, [min, max]) {\n checkNumber('Material', name, v)\n const n = /** @type {number} */ (v)\n if (n < min || n > max) fail('Material', `'${name}' must be ${max === Infinity ? `${min} or more` : `${min}-${max}`}, got ${n}`)\n return n\n}\n","// Turns the option objects drawables accept into Geometry and Material. Only objects that need no\n// extra code: generator descriptions such as { type: 'box' } go through create(), so an app that\n// never uses descriptions doesn't carry every generator.\nimport { Geometry } from './geometry/Geometry.js'\nimport { Material } from './material/Material.js'\nimport { describe, fail } from './validate.js'\n\n/** @import { MaterialOptions } from './material/Material.js' */\n/** @import { GeometryOptions } from './geometry/Geometry.js' */\n\n/**\n * @param {Geometry | GeometryOptions} input a Geometry, or its options ({ positions, indices, ... })\n * @param {string} owner\n * @returns {Geometry}\n */\nexport function resolveGeometry(input, owner) {\n if (input instanceof Geometry) return input\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n fail(owner, `'geometry' must be a Geometry such as box(2), got ${describe(input)}`)\n }\n if ('type' in input) {\n const type = /** @type {{ type: unknown }} */ (input).type\n fail(owner, `'geometry' { type: '${type}' } is a description - use the generator directly, e.g. ` +\n `${type}(...), or build the whole node with create({ type: '${owner.toLowerCase()}', geometry: { type: '${type}' } })`)\n }\n return new Geometry(/** @type {GeometryOptions} */ (input))\n}\n\n/**\n * @param {Material | MaterialOptions | undefined} input\n * @returns {Material}\n */\nexport function resolveMaterial(input) {\n return input === undefined ? new Material() : Material.fromInput(input)\n}\n","// 3x3 matrices as column-major Float32Array(9). Signatures follow gl-matrix.\n\n/** @returns {Float32Array} identity */\nexport function create() {\n return identity(new Float32Array(9))\n}\n\n/** @template {Float32Array | number[]} T @param {T} out @returns {T} */\nexport function identity(out) {\n out.fill(0)\n out[0] = out[4] = out[8] = 1\n return out\n}\n\n// Inverse transpose of a 4x4 matrix's upper 3x3 - transforms normals correctly under\n// non-uniform scale. Returns null if the matrix can't be inverted.\n/** @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a 4x4 @returns {T | null} */\nexport function normalFromMat4(out, a) {\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]\n\n const b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10\n const b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11\n const b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12\n const b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30\n const b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31\n const b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32\n\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06\n if (!det) return null\n det = 1 / det\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det\n out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det\n out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det\n out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det\n out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det\n out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det\n out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det\n out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det\n out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det\n return out\n}\n\n/** The upper-left 3x3 of a 4x4. @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @returns {T} */\nexport function fromMat4(out, a) {\n out[0] = a[0]; out[1] = a[1]; out[2] = a[2]\n out[3] = a[4]; out[4] = a[5]; out[5] = a[6]\n out[6] = a[8]; out[7] = a[9]; out[8] = a[10]\n return out\n}\n","import * as mat3 from '../math/mat3.js'\nimport * as mat4 from '../math/mat4.js'\nimport * as quat from '../math/quat.js'\nimport { Box3 } from '../value/Box3.js'\nimport { Color } from '../value/Color.js'\nimport { Euler } from '../value/Euler.js'\nimport { Mat4 } from '../value/Mat4.js'\nimport { Quat } from '../value/Quat.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { checkOptions, describe, fail } from '../validate.js'\nimport { Clip } from '../clip.js'\n\n/** @import { ColorInput, QuatInput, Vec3Input } from '../types.js' */\n/** @import { Hit } from '../Raycaster.js' */\n/** @import { Camera } from './cameras.js' */\n/** @import { ClipOptions } from '../clip.js' */\n/** @import { Ray } from '../value/Ray.js' */\n\n/**\n * A drag in progress, given to onDrag handlers: 'start' once the pointer has moved off where it\n * was pressed, 'move' as it moves, 'end' when it lets go.\n * @typedef {object} Drag\n * @property {'start' | 'move' | 'end'} phase\n * @property {Hit} hit what was pressed\n * @property {Node} node the node whose handler this is (the hit's, or the nearest above it with one)\n * @property {Ray} ray the pointer's ray now, in world space\n * @property {{ normal: Vec3, point: Vec3 }} plane what it is dragged across - horizontal through the\n * pressed point unless the handler sets another at 'start'\n * @property {Vec3} start where the drag began on the plane\n * @property {Vec3 | null} point where the pointer is on the plane now (null if it has left the plane, as at the horizon)\n * @property {Vec3} delta point - start (the last good point's, when it has left the plane)\n * @property {PointerEvent} event\n */\n\n/** @typedef {{ color: Color, width: number }} Outline */\n\n/**\n * Per-frame behaviour: `(node, dt, t) => void`, with dt and t in seconds.\n * @typedef {(node: any, dt: number, t: number) => void} UpdateHandler\n */\n\n/**\n * @typedef {object} NodeOptions\n * @property {string} [name]\n * @property {Vec3Input} [position]\n * @property {Vec3Input | Euler} [rotation] Euler angles in radians, XYZ order\n * @property {QuatInput} [quaternion] [x, y, z, w] or { x, y, z, w } - instead of rotation\n * @property {Vec3Input | number} [scale] a number scales uniformly\n * @property {boolean} [visible]\n * @property {boolean} [pickable] include in view.pick() (default true)\n * @property {boolean} [matrixAutoUpdate] recompose the local matrix each frame (default true)\n * @property {Node[]} [children]\n * @property {Record<string, unknown>} [userData] anything of your own\n * @property {UpdateHandler | UpdateHandler[]} [onUpdate]\n * @property {((hit: Hit) => any) | null} [tooltip] tooltip for anything picked in this subtree; nearer nodes win, and\n * all win over the View's\n * @property {ColorInput | null | false} [highlight] hover tint for this subtree, over the View's; false for none - a\n * floor or wall left plain under a View that tints everything else (null: the View's)\n * @property {boolean} [highlightWhole] hovering any part of this subtree tints all of it, as one thing - a\n * piece of furniture, a machine - rather than just the part under the pointer (default false)\n * @property {((hit: Hit | null) => void) | null} [onHover] called as the thing under the pointer in this subtree changes\n * (null when it leaves the subtree)\n * @property {((hit: Hit) => void) | null} [onClick] called when something in this subtree is clicked\n * @property {((camera: Camera) => boolean) | null} [showFrom] draw this subtree only for cameras this returns true for\n * @property {((drag: Drag) => void) | null} [onDrag] drag this subtree with the pointer: called as a drag starts, moves and ends\n * (the camera stays still meanwhile); a press without a drag still clicks\n * @property {ColorInput | { color?: ColorInput, width?: number } | null} [outline] draw a line round this subtree's silhouette, on top of\n * everything - for selection. A colour, or { color, width } with width in pixels (default 2)\n * @property {ClipOptions | Clip | null} [clip] cut away everything in this subtree on one side of a plane in this\n * node's space - for cutaways. The nearest clip above a mesh is the one that cuts it\n */\n\nexport const NODE_OPTIONS = ['name', 'position', 'rotation', 'quaternion', 'scale', 'visible', 'pickable',\n 'matrixAutoUpdate', 'children', 'userData', 'onUpdate', 'tooltip', 'highlight', 'highlightWhole', 'onHover', 'onClick', 'showFrom', 'clip', 'onDrag', 'outline']\n\n// three.js habits that would otherwise fail with a plain \"unknown option\"\nexport const NODE_HINTS = {\n rotationX: \"use rotation: [x, y, z] (radians)\",\n scaleX: 'use scale: [x, y, z] or a single number',\n translate: \"use position: [x, y, z]\",\n parent: 'add the node to its parent instead: parent.add(node)',\n type: \"'type' is only used in descriptions passed to create() or add()\",\n clippingPlanes: 'use clip: { normal, offset, cap } - one plane, cutting this node and everything under it',\n draggable: 'give the node an onDrag handler: onDrag: (drag) => { ... }',\n onDragStart: \"use onDrag - drag.phase is 'start', 'move' or 'end'\",\n onDragEnd: \"use onDrag - drag.phase is 'start', 'move' or 'end'\",\n selected: \"outline what's selected: node.outline = '#ffcc00'\",\n}\n\n/** @type {Function[]} */\nconst NO_HANDLERS = []\nconst UP = new Float32Array([0, 1, 0])\nconst tmpMat = new Float32Array(16)\nconst tmpMat3 = new Float32Array(9)\n\n/** The base of everything in a scene: a transform (position, rotation, scale) and children. */\nexport class Node {\n /** The description type, used by create() and toJSON(). */\n static type = 'node'\n /**\n * The options it takes, and hints for names people reach for instead. A subclass with options of\n * its own adds to its parent's: static get OPTIONS() { return [...super.OPTIONS, 'blink'] }\n * @type {string[]}\n */\n static OPTIONS = NODE_OPTIONS\n /** @type {Record<string, string>} */\n static HINTS = NODE_HINTS\n\n name = ''\n #position = new Vec3()\n #scale = new Vec3(1, 1, 1)\n #quaternion = new Quat()\n #rotation = new Euler()\n visible = true\n /** Include in picking. */\n pickable = true\n /** Recompose the local matrix from position/rotation/scale each frame. */\n matrixAutoUpdate = true\n /** Local transform. @type {Mat4} */ matrix = new Mat4()\n /** Read only: parent's world matrix x local matrix, as of the last update. @type {Mat4} */\n worldMatrix = new Mat4()\n /** Anything of your own; copied by clone() and kept in toJSON() when it is plain data. */\n userData = {}\n /** Tooltip for anything picked in this subtree (nearest wins, over the View's). @type {((hit: Hit) => any) | null} */\n tooltip = null\n /** Called as the thing under the pointer in this subtree changes; null when it leaves. @type {((hit: Hit | null) => void) | null} */\n onHover = null\n /** Called when something in this subtree is clicked. @type {((hit: Hit) => void) | null} */\n onClick = null\n /** Draw this subtree only for cameras this returns true for - per frame, without changing the scene. @type {((camera: Camera) => boolean) | null} */\n showFrom = null\n /** @internal An HTML element shown over the canvas while this node is drawn (a chart's legend). @type {HTMLElement | null} */\n overlay = null\n /** @type {Clip | null} */\n #clip = null\n /** Called as the pointer drags this subtree: see Drag. @type {((drag: Drag) => void) | null} */\n onDrag = null\n /** @type {Outline | null} */\n #outline = null\n /** @type {Color | null | false} */\n #highlight = null\n /** Hovering any part of this subtree tints all of it, not just the part under the pointer. */\n highlightWhole = false\n /** Hover and click listeners besides onHover and onClick, made on the first on(). @type {{ hover: Set<Function>, click: Set<Function> } | null} */\n #listeners = null\n\n /** @type {Node | null} */\n #parent = null\n /** @type {Node[]} */\n #children = []\n /** @type {UpdateHandler[]} */\n #handlers = []\n\n /** Where it is, in its parent's space. Assigning copies the value in: node.position = [1, 2, 3]. @returns {Vec3} */\n get position() { return this.#position }\n /** @param {Vec3Input} v */\n set position(v) { this.#position.copy(v, this.constructor.name) }\n /** Its size along each axis; assigning copies, and a number scales all three. @returns {Vec3} */\n get scale() { return this.#scale }\n /** @param {Vec3Input | number} v */\n set scale(v) { this.#scale.copy(/** @type {any} */ (v), this.constructor.name) }\n /** Euler angles in radians, XYZ order; kept in sync with quaternion. Assigning copies. @returns {Euler} */\n get rotation() { return this.#rotation }\n /** @param {Vec3Input} v */\n set rotation(v) { this.#rotation.copy(/** @type {any} */ (v), this.constructor.name) }\n /** Kept in sync with rotation. Assigning copies, normalised. @returns {Quat} */\n get quaternion() { return this.#quaternion }\n /** @param {QuatInput} v */\n set quaternion(v) { this.#quaternion.copy(v, this.constructor.name).normalize() }\n\n /** @param {NodeOptions} [options] */\n constructor(options = {}) {\n const Class = /** @type {typeof Node & { OPTIONS?: string[], HINTS?: Record<string, string> }} */ (new.target)\n checkOptions(Class.name, options, Class.OPTIONS, { ...NODE_HINTS, ...Class.HINTS })\n this.rotation.onChange = () => quat.fromEulerXYZ(this.quaternion, this.rotation.x, this.rotation.y, this.rotation.z)\n this.quaternion.onChange = () => this.rotation.setFromQuat(this.quaternion)\n\n const owner = Class.name\n if (options.name !== undefined) this.name = String(options.name)\n if (options.position !== undefined) this.position.copy(options.position, owner)\n if (options.rotation !== undefined) this.rotation.copy(/** @type {any} */ (options.rotation), owner)\n if (options.quaternion !== undefined) this.quaternion.copy(options.quaternion, owner).normalize()\n if (options.scale !== undefined) this.scale.copy(options.scale, owner)\n if (options.visible !== undefined) this.visible = !!options.visible\n if (options.pickable !== undefined) this.pickable = !!options.pickable\n if (options.matrixAutoUpdate !== undefined) this.matrixAutoUpdate = !!options.matrixAutoUpdate\n if (options.userData !== undefined) this.userData = options.userData\n if (options.onUpdate) [options.onUpdate].flat().forEach((fn) => this.onUpdate(fn))\n for (const key of ['tooltip', 'onHover', 'onClick', 'showFrom', 'onDrag']) {\n const fn = options[key]\n if (fn === undefined || fn === null) continue\n if (typeof fn !== 'function') fail(owner, `'${key}' must be a function, got ${describe(fn)}`)\n this[key] = fn\n }\n if (options.highlight != null) this.#setHighlight(options.highlight, owner)\n if (options.highlightWhole !== undefined) {\n if (typeof options.highlightWhole !== 'boolean') fail(owner, `'highlightWhole' must be true or false, got ${describe(options.highlightWhole)}`)\n this.highlightWhole = options.highlightWhole\n }\n if (options.clip != null) this.#clip = Clip.fromInput(options.clip, owner)\n if (options.outline != null) this.#setOutline(options.outline)\n if (options.children) for (const child of options.children) this.add(child)\n }\n\n /**\n * Hover tint for this subtree, over the View's: a colour, false for none, or null to use the View's.\n * @returns {Color | null | false}\n */\n get highlight() {\n return this.#highlight\n }\n\n /** @param {ColorInput | null | false} value */\n set highlight(value) {\n this.#setHighlight(value, this.constructor.name)\n }\n\n /** @param {ColorInput | null | false | true} value @param {string} owner */\n #setHighlight(value, owner) {\n if (value === true) fail(owner, \"'highlight' is a colour, false for no tint, or null to use the View's - got true\")\n this.#highlight = value == null ? null : value === false ? false : Color.fromInput(value, owner)\n }\n\n /**\n * The section plane cutting this subtree, or null. Set { normal, offset, cap }, a Clip or null;\n * move the cut by changing its offset or normal in place.\n * @returns {Clip | null}\n */\n get clip() {\n return this.#clip\n }\n\n /** @param {ClipOptions | Clip | null} value */\n set clip(value) {\n this.#clip = value == null ? null : Clip.fromInput(value, this.constructor.name)\n }\n\n /**\n * A line round this subtree's silhouette, drawn over everything - for showing what is selected -\n * or null. Set a colour, { color, width } (pixels, default 2) or null.\n * @returns {Outline | null}\n */\n get outline() {\n return this.#outline\n }\n\n /** @param {ColorInput | { color?: ColorInput, width?: number } | null} value */\n set outline(value) {\n this.#setOutline(value)\n }\n\n /** @param {ColorInput | { color?: ColorInput, width?: number } | null} value */\n #setOutline(value) {\n const owner = this.constructor.name\n if (value == null) {\n this.#outline = null\n return\n }\n const options = typeof value === 'object' && !Array.isArray(value) && !ArrayBuffer.isView(value) && !(value instanceof Color)\n ? /** @type {{ color?: ColorInput, width?: number }} */ (value) : { color: /** @type {ColorInput} */ (value) }\n checkOptions(owner, options, ['color', 'width'], {}, 'outline')\n const width = options.width ?? 2\n if (typeof width !== 'number' || !(width > 0) || width > 8) fail(owner, `'outline.width' is in pixels, above 0 and up to 8, got ${describe(width)}`)\n this.#outline = { color: Color.fromInput(options.color ?? '#ffcc00', owner), width }\n }\n\n /** @returns {Node | null} */\n get parent() {\n return this.#parent\n }\n\n /** Read only - use add() and remove(). @returns {readonly Node[]} */\n get children() {\n return this.#children\n }\n\n /** The topmost ancestor (the scene, once added to one). @returns {Node} */\n get root() {\n /** @type {Node} */\n let n = this\n while (n.#parent) n = n.#parent\n return n\n }\n\n /**\n * Add children. Returns the first one, so `const cube = scene.add(new Mesh({...}))` keeps a\n * reference. A list works too: `group.add(...parts)`. For a description, add(create({ type: 'mesh', ... })).\n * @template {Node} T\n * @param {T} [first] (optional only in its type, so a spread list type-checks - add() needs one)\n * @param {...Node} more\n * @returns {T}\n */\n add(first, ...more) {\n if (first === undefined) fail(this.constructor.name, 'add() needs a node to add - add(new Mesh({...})), or add(...nodes) for several')\n const nodes = [first, ...more].map((n) => toNode(n))\n for (const node of nodes) {\n if (node === this) fail(this.constructor.name, \"can't add a node to itself\")\n for (let p = this.#parent; p; p = p.#parent) {\n if (p === node) fail(this.constructor.name, \"can't add an ancestor as a child - that would make a loop\")\n }\n if (node.#parent) node.#parent.#detach(node)\n node.#parent = this\n this.#children.push(node)\n }\n return /** @type {T} */ (nodes[0])\n }\n\n /** Remove children. Safe inside update handlers and traverse(): the walk goes on over the children as they were. @param {...Node} nodes @returns {this} */\n remove(...nodes) {\n for (const node of nodes) {\n if (node.#parent === this) this.#detach(node)\n }\n return this\n }\n\n /** @returns {this} */\n removeFromParent() {\n this.#parent?.remove(this)\n return this\n }\n\n /** @param {Node} node */\n #detach(node) {\n this.#children.splice(this.#children.indexOf(node), 1)\n node.#parent = null\n }\n\n /**\n * Visit this node and every descendant, depth first. The children are copied before they are\n * visited, so fn can remove or move nodes without the walk skipping one.\n * @param {(node: Node) => void} fn\n */\n traverse(fn) {\n fn(this)\n if (this.#children.length) for (const child of [...this.#children]) child.traverse(fn)\n }\n\n /** The first descendant (or this) with a name. @param {string} name @returns {Node | undefined} */\n find(name) {\n if (this.name === name) return this\n for (const child of this.#children) {\n const found = child.find(name)\n if (found) return found\n }\n return undefined\n }\n\n /** Every descendant (and this) matching a predicate. @param {(node: Node) => boolean} predicate @returns {Node[]} */\n findAll(predicate) {\n /** @type {Node[]} */\n const found = []\n this.traverse((n) => predicate(n) && found.push(n))\n return found\n }\n\n /**\n * Per-frame behaviour: node.onUpdate((node, dt, t) => {}) adds a handler and returns a function\n * that removes it. A node can have several, so it's called, not assigned like onClick.\n * @returns {(fn: UpdateHandler) => () => void}\n */\n get onUpdate() { return (fn) => this.#addUpdate(fn) }\n /** @param {unknown} _fn */\n set onUpdate(_fn) {\n fail(this.constructor.name, \"call onUpdate rather than assigning it - node.onUpdate((node, dt, t) => {}) adds a handler (a node can have several)\")\n }\n\n /** @param {UpdateHandler} fn @returns {() => void} */\n #addUpdate(fn) {\n if (typeof fn !== 'function') fail(this.constructor.name, `onUpdate expects a function (node, dt, t) => {}, got ${describe(fn)}`)\n this.#handlers.push(fn)\n return () => {\n const i = this.#handlers.indexOf(fn)\n if (i !== -1) this.#handlers.splice(i, 1)\n }\n }\n\n /**\n * Listen for the pointer on this subtree as well as its own onHover and onClick - for add-ons, and\n * anything that mustn't replace the app's handler. Returns a function that stops listening. (A drag\n * has one handler, onDrag: one thing moves a node at a time.)\n * @param {'hover' | 'click'} event\n * @param {(hit: Hit | null) => void} fn hover hears null when the pointer leaves\n * @returns {() => void}\n */\n on(event, fn) {\n const owner = this.constructor.name\n if (event !== 'hover' && event !== 'click') fail(owner, `on() listens for 'hover' or 'click', got ${describe(event)}${event === 'drag' ? \" - a drag has one handler: onDrag\" : ''}`)\n if (typeof fn !== 'function') fail(owner, `on('${event}', fn) needs a function, got ${describe(fn)}`)\n this.#listeners ??= { hover: new Set(), click: new Set() }\n const set = this.#listeners[event]\n set.add(fn)\n return () => { set.delete(fn) }\n }\n\n /** @internal Everything to tell of the pointer on this node: its own handler, then its listeners. @param {'hover' | 'click'} event @returns {Function[]} */\n handlersFor(event) {\n const own = event === 'hover' ? this.onHover : this.onClick\n const more = this.#listeners?.[event]\n if (!more?.size) return own ? [own] : NO_HANDLERS\n return own ? [own, ...more] : [...more]\n }\n\n /** @internal Run this node's update handlers. @param {number} dt @param {number} t */\n runHandlers(dt, t) {\n for (const fn of this.#handlers) fn(this, dt, t)\n }\n\n /** @internal @returns {boolean} */\n get hasHandlers() {\n return this.#handlers.length > 0\n }\n\n // ---- transforms: all chainable, and all in the node's local frame ----\n\n /** @param {number} x @param {number} y @param {number} z @returns {this} */\n translate(x, y, z) {\n const offset = new Vec3(x, y, z).applyQuaternion(this.quaternion)\n this.position.add(offset)\n return this\n }\n\n /** @param {number} d @returns {this} */\n translateX(d) { return this.translate(d, 0, 0) }\n /** @param {number} d @returns {this} */\n translateY(d) { return this.translate(0, d, 0) }\n /** @param {number} d @returns {this} */\n translateZ(d) { return this.translate(0, 0, d) }\n\n /** Rotate about a local axis. @param {Vec3Input} axis @param {number} rad @returns {this} */\n rotate(axis, rad) {\n const a = Vec3.fromInput(axis, this.constructor.name).normalize()\n this.quaternion.multiply(new Quat().setFromAxisAngle(a, rad))\n return this\n }\n\n /** @param {number} rad @returns {this} */\n rotateX(rad) { return this.rotate([1, 0, 0], rad) }\n /** @param {number} rad @returns {this} */\n rotateY(rad) { return this.rotate([0, 1, 0], rad) }\n /** @param {number} rad @returns {this} */\n rotateZ(rad) { return this.rotate([0, 0, 1], rad) }\n\n /**\n * Turn so the node's -Z axis points at a world position or node (cameras and lights look down -Z),\n * with its +Y leaning toward up - a world direction, +Y unless given. The roll is undefined when\n * looking straight along up, so for something that turns through every heading in a plane - a\n * craft seen face on, moving in x-y - give an up out of that plane: [0, 0, 1].\n * @param {Vec3Input | Node} target\n * @param {Vec3Input} [up]\n * @returns {this}\n */\n lookAt(target, up) {\n const at = target instanceof Node ? target.updateWorld().worldPosition : Vec3.fromInput(target, this.constructor.name)\n const toward = up === undefined ? UP : Vec3.fromInput(up, `${this.constructor.name}.lookAt() up`).normalize()\n this.updateWorld()\n const eye = this.worldPosition\n if (eye.equals(at, 1e-9)) return this\n // looking straight along up needs a different one\n const dir = at.clone().sub(eye).normalize()\n const along = Math.abs(dir.dot(toward)) > 0.9999\n const lean = along ? (Math.abs(toward[1]) > 0.9 ? [0, 0, -1] : UP) : toward\n mat4.targetTo(tmpMat, eye, at, lean)\n const world = quat.fromMat3(new Float32Array(4), mat3.fromMat4(tmpMat3, tmpMat))\n // into the parent's frame\n if (this.#parent) {\n const parentRot = quat.normalize(new Float32Array(4), quat.fromMat3(new Float32Array(4), normalizedRotation(this.#parent.worldMatrix)))\n quat.multiply(world, quat.invert(parentRot, parentRot), world)\n }\n this.quaternion.copy(quat.normalize(world, world))\n return this\n }\n\n /** Recompose `matrix` from position, rotation and scale. @returns {this} */\n updateMatrix() {\n this.matrix.compose(this.position, this.quaternion, this.scale)\n return this\n }\n\n /**\n * Bring world matrices up to date: this node's ancestors, then this node and its descendants.\n * Scenes do this every frame; call it to read world values in between.\n * @returns {this}\n */\n updateWorld() {\n if (this.#parent) this.#parent.#updateAncestors()\n this.updateWorldTree()\n return this\n }\n\n #updateAncestors() {\n if (this.#parent) this.#parent.#updateAncestors()\n this.#updateSelf()\n }\n\n #updateSelf() {\n if (this.matrixAutoUpdate) this.updateMatrix()\n if (this.#parent) mat4.multiply(this.worldMatrix, this.#parent.worldMatrix, this.matrix)\n else this.worldMatrix.copy(this.matrix)\n }\n\n /**\n * Bring the world matrices of this node and everything under it up to date now, from the parent's\n * current world matrix - before reading worldPosition or bounds after moving things, without\n * waiting for the next frame.\n */\n updateWorldTree() {\n this.#updateSelf()\n for (const child of this.#children) child.updateWorldTree()\n }\n\n /** World position as of the last update. @returns {Vec3} */\n get worldPosition() {\n return this.worldMatrix.getPosition()\n }\n\n /** World rotation as of the last update. @returns {Quat} */\n get worldQuaternion() {\n const q = quat.fromMat3(new Float32Array(4), normalizedRotation(this.worldMatrix))\n return new Quat(q[0], q[1], q[2], q[3]).normalize()\n }\n\n /** World scale as of the last update. @returns {Vec3} */\n get worldScale() {\n return this.worldMatrix.getScale()\n }\n\n /** World space bounds of this node and its descendants, brought up to date first. @returns {Box3} */\n get bounds() {\n this.updateWorld()\n const box = new Box3()\n this.traverse((n) => n.expandBounds(box))\n return box\n }\n\n /**\n * The world-space box of what a camera draws of this subtree: like bounds, but leaving out hidden\n * nodes and those whose showFrom turns them away from that camera - a chart's axis labels for\n * the edges it isn't showing, say. Framing fits this, so the picture fills the view.\n * @param {Camera} camera\n * @returns {Box3}\n */\n boundsFrom(camera) {\n this.updateWorld()\n const box = new Box3()\n this.eachShownTo(camera, (n) => n.expandBounds(box))\n return box\n }\n\n /** @internal\n * Does this camera draw this node (leaving its ancestors aside)? Visible, and not turned away by\n * showFrom. The one rule drawing, picking, framing and redraw-watching all use.\n * @param {Camera} camera\n * @returns {boolean}\n */\n shownTo(camera) {\n return this.visible && (!this.showFrom || this.showFrom(camera))\n }\n\n /** @internal Visit this node and every descendant the camera draws - a hidden node's subtree is skipped. @param {Camera} camera @param {(node: Node) => void} fn */\n eachShownTo(camera, fn) {\n if (!this.shownTo(camera)) return\n fn(this)\n for (const child of this.#children) child.eachShownTo(camera, fn)\n }\n\n /** @internal Grow a world space box by this node's own geometry (none for a plain node). @param {Box3} box */\n expandBounds(box) {\n return box\n }\n\n /**\n * A copy of this node; with `deep` (the default) its children are cloned too. Geometry and\n * materials are shared, not copied.\n * @param {{ deep?: boolean }} [options]\n * @returns {this}\n */\n clone({ deep = true } = {}) {\n const Class = /** @type {any} */ (this.constructor)\n const copy = new Class(this.cloneOptions())\n copy.userData = structuredClone(this.userData)\n copy.matrixAutoUpdate = this.matrixAutoUpdate\n if (!copy.matrixAutoUpdate) copy.matrix.copy(this.matrix)\n for (const fn of this.#handlers) copy.onUpdate(fn)\n if (deep) for (const child of this.#children) copy.add(child.clone())\n return copy\n }\n\n /** @internal Constructor options that recreate this node (without children). @returns {Record<string, unknown>} */\n cloneOptions() {\n return {\n name: this.name,\n position: this.position.toArray(),\n quaternion: this.quaternion.toArray(),\n scale: this.scale.toArray(),\n visible: this.visible,\n pickable: this.pickable,\n tooltip: this.tooltip,\n highlight: this.highlight,\n highlightWhole: this.highlightWhole,\n onHover: this.onHover,\n onClick: this.onClick,\n showFrom: this.showFrom,\n clip: this.#clip ? this.#clip.toJSON() : null,\n onDrag: this.onDrag,\n outline: this.#outline ? { color: this.#outline.color.getStyle(), width: this.#outline.width } : null,\n }\n }\n\n /**\n * This node and its descendants as a plain description that create() rebuilds. Handlers are\n * behaviour, not data, and are left out.\n * @returns {Record<string, unknown>}\n */\n toJSON() {\n /** @type {Record<string, unknown>} */\n const json = { type: /** @type {typeof Node} */ (this.constructor).type }\n if (this.name) json.name = this.name\n if (!this.position.equals([0, 0, 0])) json.position = this.position.toArray()\n if (this.rotation.x || this.rotation.y || this.rotation.z) json.rotation = this.rotation.toArray()\n if (!this.scale.equals([1, 1, 1])) json.scale = this.scale.toArray()\n if (!this.visible) json.visible = false\n if (!this.pickable) json.pickable = false\n if (!this.matrixAutoUpdate) json.matrixAutoUpdate = false\n if (this.highlight) json.highlight = this.highlight.getStyle()\n else if (this.highlight === false) json.highlight = false\n if (this.highlightWhole) json.highlightWhole = true\n if (this.#clip) json.clip = this.#clip.toJSON()\n if (this.#outline) json.outline = { color: this.#outline.color.getStyle(), width: this.#outline.width }\n if (Object.keys(this.userData).length) json.userData = this.userData\n Object.assign(json, this.jsonOptions())\n if (this.#children.length) json.children = this.#children.map((c) => c.toJSON())\n return json\n }\n\n /** @internal Subclass-specific description fields. @returns {Record<string, unknown>} */\n jsonOptions() {\n return {}\n }\n\n /** Release GPU resources used by this subtree (shared resources are released by the renderer only when unused). */\n dispose() {\n this.traverse((n) => n !== this && n.dispose())\n }\n}\n\n/**\n * A point property's new value: copied into the vector it has, so references to it stay good, or\n * null to clear it. @internal\n * @param {Vec3 | null} current @param {import('../types.js').Vec3Input | null | undefined} v @param {string} owner\n * @returns {Vec3 | null}\n */\nexport function setPoint(current, v, owner) {\n if (v === null || v === undefined) return null\n return current ? current.copy(v, owner) : Vec3.fromInput(v, owner)\n}\n\n/**\n * @internal Where a world position or node is in a node's parent's space - the space its position,\n * and a camera's or light's target, are in.\n * @param {Node} node @param {Vec3Input | Node} target\n * @returns {Vec3}\n */\nexport function inParentSpace(node, target) {\n const at = target instanceof Node ? target.updateWorld().worldPosition : Vec3.fromInput(target, `${node.constructor.name}.lookAt()`)\n const parent = node.parent\n return parent ? at.applyMatrix4(parent.updateWorld().worldMatrix.clone().invert()) : at\n}\n\n/** @param {unknown} n @returns {Node} */\nfunction toNode(n) {\n if (n instanceof Node) return n\n if (n && typeof n === 'object' && 'type' in n) {\n return fail('Node', `add() takes nodes - build one from a description with add(create({ type: '${n.type}', ... }))`)\n }\n return fail('Node', `add() expects nodes, got ${describe(n)}`)\n}\n\n// The rotation part of a matrix with any scale divided out, as a 3x3.\n/** @param {Float32Array} m @returns {Float32Array} */\nfunction normalizedRotation(m) {\n const out = mat3.fromMat4(new Float32Array(9), m)\n for (let c = 0; c < 3; c++) {\n const len = Math.hypot(out[c * 3], out[c * 3 + 1], out[c * 3 + 2]) || 1\n out[c * 3] /= len\n out[c * 3 + 1] /= len\n out[c * 3 + 2] /= len\n }\n return out\n}\n\n/** A node for grouping others - nothing more. */\nexport class Group extends Node {\n static type = 'group'\n}\n","import * as mat4 from '../math/mat4.js'\nimport { Color } from '../value/Color.js'\nimport { Euler } from '../value/Euler.js'\nimport { Quat } from '../value/Quat.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { checkNumber, checkOneOf, describe, fail } from '../validate.js'\nimport { resolveGeometry, resolveMaterial } from '../resolve.js'\nimport { NODE_OPTIONS, Node } from './Node.js'\n\n/** @import { Box3 } from '../value/Box3.js' */\n/** @import { Geometry } from '../geometry/Geometry.js' */\n/** @import { Material, MaterialOptions } from '../material/Material.js' */\n/** @import { GeometryOptions } from '../geometry/Geometry.js' */\n/** @import { NodeOptions } from './Node.js' */\n/** @import { ColorInput, QuatInput, Vec3Input } from '../types.js' */\n\n/**\n * @typedef {NodeOptions & {\n * geometry: Geometry | GeometryOptions,\n * material?: Material | MaterialOptions,\n * castShadow?: boolean,\n * receiveShadow?: boolean,\n * renderOrder?: number,\n * frustumCulled?: boolean,\n * data?: unknown,\n * }} DrawableOptions\n * data: what this node shows - picking hands it back as hit.datum. An array is one row per instance\n * (InstancedMesh), point (Points) or segment (Lines); on a Mesh, an array as long as its vertices is\n * a row per vertex, and a hit gives the nearest vertex's row (a surface).\n */\n\n/**\n * Where a label sits and how it competes for space.\n * @typedef {object} LabelPlacement\n * @property {LabelPlace} [place] where the label goes relative to its point (default 'center')\n * @property {[number, number]} [offset] extra shift in CSS pixels, +y down (default [0, 0])\n * @property {string} [className] CSS class(es) for the label element\n * @property {number} [priority] when labels overlap, the higher priority stays (default 0)\n * @property {'hide' | 'dim' | 'show'} [overlap] when the label is covered - by a higher-priority label, or by\n * geometry with occlude - 'hide' drops it, 'dim' draws it faint and behind; 'show' always shows it (default 'hide')\n * @property {boolean} [occlude] the label counts as covered when geometry is in front of its point (default false)\n * @property {boolean} [leader] a line from the label's point to the label, with a dot on the point - for\n * callouts set off to the side with offset, as on a diagram (default false). It takes the label's text\n * colour; style it with CSS on .phoria-leader\n * @property {'left' | 'right' | null} [edge] set the label at the view's left or right edge, level with its\n * point - callouts in a column down the side of a diagram, with leader: true. offset then moves it in from\n * the edge and up or down (default null: by its point)\n * @property {number} [minScale] show the label only when zoomed in this far: at least this many CSS pixels to\n * one world unit, at the label's point - details that appear as you come closer (default 0: always)\n */\n/** @typedef {'center' | 'above' | 'below' | 'left' | 'right'} LabelPlace */\n\n/**\n * One label per instance or point, from its row of data - or a list of these, for several each (a symbol\n * always, its details when zoomed in).\n * @typedef {Omit<LabelPlacement, 'priority'> & {\n * text: (datum: any, index: number) => string | number | null | undefined,\n * priority?: number | ((datum: any, index: number) => number),\n * at?: 'top' | 'center',\n * }} InstanceLabels\n * text: the label for a row - return null for none. priority: a number, or one per row (say, by\n * status, so problems win the space). at: the instance's top (default) or centre; points always\n * label the point itself.\n */\n\nexport const LABEL_PLACES = /** @type {LabelPlace[]} */ (['center', 'above', 'below', 'left', 'right'])\nconst PLACEMENT_OPTIONS = ['place', 'offset', 'className', 'priority', 'overlap', 'occlude', 'leader', 'edge', 'minScale']\nconst LABEL_HINTS = {\n line: 'use leader: true - a line from the point to the label',\n callout: \"use leader: true, with edge: 'left' | 'right' to line the labels up down the side\",\n column: \"use edge: 'left' | 'right' - the label sits at that edge of the view, level with its point\",\n align: \"use edge: 'left' | 'right' - the label sits at that edge of the view, level with its point\",\n pointer: 'use leader: true - a line from the point to the label',\n anchor: \"use place: 'center' | 'above' | 'below' | 'left' | 'right' (where the label goes)\",\n zIndex: \"use 'priority': higher stays when labels overlap\",\n minZoom: \"use 'minScale': CSS pixels to one world unit at the label's point\",\n lod: \"use 'minScale': the label shows when zoomed in at least this far (CSS pixels to one world unit)\",\n collision: \"use overlap: 'hide' | 'dim' | 'show'\",\n}\n// labels per instance or point take one more: they can't be moved anywhere but by offset\nconst INSTANCE_LABEL_HINTS = { ...LABEL_HINTS, position: 'labels per instance sit on their instance - offset moves them in pixels' }\n\n/**\n * Validated placement options, with defaults filled in.\n * @param {string} owner @param {Record<string, any>} o\n * @returns {Required<LabelPlacement>}\n */\nfunction placement(owner, o) {\n const offset = o.offset ?? [0, 0]\n if (!Array.isArray(offset) || offset.length !== 2 || !offset.every(Number.isFinite)) {\n fail(owner, `'offset' must be [x, y] in pixels, got ${describe(offset)}`)\n }\n return {\n place: o.place === undefined ? 'center' : checkOneOf(owner, 'place', o.place, LABEL_PLACES),\n offset: /** @type {[number, number]} */ ([offset[0], offset[1]]),\n className: o.className ? String(o.className) : '',\n priority: o.priority === undefined ? 0 : checkNumber(owner, 'priority', o.priority),\n overlap: o.overlap === undefined ? 'hide' : checkOneOf(owner, 'overlap', o.overlap, ['hide', 'dim', 'show']),\n occlude: !!o.occlude,\n leader: !!o.leader,\n edge: o.edge == null ? null : /** @type {'left' | 'right'} */ (checkOneOf(owner, 'edge', o.edge, ['left', 'right'])),\n minScale: o.minScale === undefined ? 0 : minScale(owner, o.minScale),\n }\n}\n\n/** @param {string} owner @param {unknown} v @returns {number} */\nfunction minScale(owner, v) {\n const n = checkNumber(owner, 'minScale', v)\n if (!(n >= 0)) fail(owner, `'minScale' is CSS pixels to one world unit, 0 or more, got ${n}`)\n return n\n}\n\n/** @typedef {InstanceLabels & Required<Omit<LabelPlacement, 'priority'>> & { priority: number | ((datum: any, index: number) => number) }} CheckedLabels */\n\n/** @param {string} owner @param {unknown} v @returns {CheckedLabels | CheckedLabels[] | null} */\nfunction instanceLabels(owner, v) {\n if (v == null) return null\n if (Array.isArray(v)) {\n if (!v.length) fail(owner, \"'labels' as a list needs at least one { text: (datum, index) => string, ... }\")\n return v.map((one) => /** @type {CheckedLabels} */ (instanceLabels(owner, one)))\n }\n if (typeof v !== 'object' || typeof (/** @type {any} */ (v)).text !== 'function') {\n fail(owner, `'labels' must be { text: (datum, index) => string, ... }, got ${describe(v)}`)\n }\n const o = /** @type {Record<string, any>} */ (v)\n for (const key of Object.keys(o)) {\n if (key !== 'text' && key !== 'at' && !PLACEMENT_OPTIONS.includes(key)) {\n fail(owner, `unknown labels option '${key}'${INSTANCE_LABEL_HINTS[key] ? ` - ${INSTANCE_LABEL_HINTS[key]}` : ` - expected text, at, ${PLACEMENT_OPTIONS.join(', ')}`}`)\n }\n }\n const at = o.at === undefined ? 'top' : checkOneOf(owner, 'labels.at', o.at, ['top', 'center'])\n const byRow = typeof o.priority === 'function'\n const style = placement(owner, byRow ? { ...o, priority: 0 } : o)\n return { text: o.text, at, ...style, priority: byRow ? o.priority : style.priority }\n}\n\nconst DRAWABLE_OPTIONS = [...NODE_OPTIONS, 'geometry', 'material', 'castShadow', 'receiveShadow', 'renderOrder', 'frustumCulled', 'data']\n\nconst DRAWABLE_HINTS = {\n mesh: \"pass 'geometry' and 'material' directly\",\n materials: \"one 'material' per node - use a Group of meshes for several\",\n rows: \"use 'data' - one row per instance or point\",\n}\n\n/** Base for nodes with geometry and a material: Mesh, InstancedMesh, Points and Lines. */\nexport class Drawable extends Node {\n static OPTIONS = DRAWABLE_OPTIONS\n static HINTS = DRAWABLE_HINTS\n\n /** @type {Geometry} */ #geometry\n /** @type {Material} */ #material\n castShadow = false\n receiveShadow = false\n /** Draw order override within its pass; lower first. */\n renderOrder = 0\n /** Skip drawing when outside the camera's view. */\n frustumCulled = true\n /** What this node shows: one row per instance or point for InstancedMesh and Points. Picking returns it as hit.datum. */\n data = /** @type {any} */ (null)\n\n /** @param {DrawableOptions} options */\n constructor(options) {\n super(options)\n const owner = this.constructor.name\n if (!options || options.geometry === undefined) {\n fail(owner, `'geometry' is required, e.g. new ${owner}({ geometry: box(1), material: { color: 'orange' } })`)\n }\n this.#geometry = resolveGeometry(options.geometry, owner)\n this.#material = resolveMaterial(options.material)\n if (options.castShadow !== undefined) this.castShadow = !!options.castShadow\n if (options.receiveShadow !== undefined) this.receiveShadow = !!options.receiveShadow\n if (options.renderOrder !== undefined) this.renderOrder = checkNumber(owner, 'renderOrder', options.renderOrder)\n if (options.frustumCulled !== undefined) this.frustumCulled = !!options.frustumCulled\n if (options.data !== undefined) this.data = options.data\n this.checkGeometry()\n }\n\n /** What it draws. Assign a Geometry, or a description of one; it is checked as the constructor checks it. @returns {Geometry} */\n get geometry() { return this.#geometry }\n /** @param {Geometry | import('../geometry/Geometry.js').GeometryOptions} v */\n set geometry(v) {\n this.#geometry = resolveGeometry(v, this.constructor.name)\n this.checkGeometry()\n }\n\n /** How it looks. Assign a Material, or its options - mesh.material = { color: 'red' } makes one. @returns {Material} */\n get material() { return this.#material }\n /** @param {Material | import('../material/Material.js').MaterialOptions} v */\n set material(v) { this.#material = resolveMaterial(v) }\n\n /** @internal\n * The data for a hit: this node's row at `index` when data is an array and the node draws many\n * things (instances, points, line segments), otherwise the data itself.\n * @param {number | null} index\n * @returns {any}\n */\n datumAt(index) {\n const many = 'instanceMatrices' in this || this.drawMode !== 'triangles'\n if (many && Array.isArray(this.data)) return index === null ? null : this.data[index] ?? null\n return this.data ?? null\n }\n\n /** True for anything with geometry and a material - lets renderers test without importing this class. */\n get isDrawable() {\n return true\n }\n\n /** How the geometry is drawn: 'triangles', 'points' or 'lines'. @returns {'triangles' | 'points' | 'lines'} */\n get drawMode() {\n return 'triangles'\n }\n\n /** @internal Subclasses check the geometry suits them. */\n checkGeometry() {}\n\n /** @internal @param {Box3} box */\n expandBounds(box) {\n if (this.geometry.vertexCount) box.union(this.geometry.bounds.clone().applyMatrix4(this.worldMatrix))\n return box\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return {\n ...super.cloneOptions(),\n geometry: this.geometry,\n material: this.material,\n castShadow: this.castShadow,\n receiveShadow: this.receiveShadow,\n renderOrder: this.renderOrder,\n frustumCulled: this.frustumCulled,\n data: this.data,\n }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = { geometry: this.geometry.toJSON(), material: this.material.toJSON() }\n if (this.castShadow) json.castShadow = true\n if (this.receiveShadow) json.receiveShadow = true\n if (this.renderOrder) json.renderOrder = this.renderOrder\n if (!this.frustumCulled) json.frustumCulled = false\n if (this.data != null) json.data = this.data\n return json\n }\n\n /** Release this node's geometry, material and textures from the GPU (and its children's). */\n dispose() {\n this.geometry.dispose()\n this.material.dispose()\n for (const [, t] of this.material.textures) t.dispose()\n super.dispose()\n }\n}\n\n/** Triangles: the usual solid object. */\nexport class Mesh extends Drawable {\n static type = 'mesh'\n\n /** @internal */\n checkGeometry() {\n const n = this.geometry.elementCount\n if (n % 3 !== 0) {\n fail('Mesh', `geometry has ${n} ${this.geometry.indices ? 'indices' : 'vertices'}, not a multiple of 3 - ` +\n 'triangles need three each (use Lines for pairs, Points for single vertices)')\n }\n }\n}\n\n/**\n * @typedef {object} InstanceOptions\n * @property {Vec3Input} [position]\n * @property {Vec3Input | Euler} [rotation] Euler angles in radians, XYZ order\n * @property {QuatInput} [quaternion] [x, y, z, w] or { x, y, z, w } - as physics engines give them\n * @property {Vec3Input | number} [scale]\n * @property {ColorInput} [color] multiplies the material colour\n */\n\nconst INSTANCE_OPTIONS = new Set(['position', 'rotation', 'quaternion', 'scale', 'color'])\n// reused by setInstance, so updating every instance of a large mesh each frame allocates nothing\nconst scratch = { position: new Vec3(), scale: new Vec3(), quaternion: new Quat(), rotation: new Euler() }\nconst SCRATCH_COLOR = new Color()\nconst scratchMatrix = new Float32Array(16)\n\n/**\n * True when an instance is scaled to nothing - hidden: it draws nothing, takes no room in its mesh's\n * bounds and shows no label.\n * @internal @param {ArrayLike<number>} m instance matrices @param {number} i\n */\nexport function hiddenInstance(m, i) {\n const o = i * 16\n return !m[o] && !m[o + 1] && !m[o + 2] && !m[o + 4] && !m[o + 5] && !m[o + 6] && !m[o + 8] && !m[o + 9] && !m[o + 10]\n}\n\n/**\n * Many copies of one geometry and material, drawn together. Set each copy with setInstance().\n * Picking reports which instance was hit. An instance scaled to 0 is hidden - it draws nothing, and\n * framing, culling, shadows and labels leave it out - so a pool of instances can keep spares.\n */\nexport class InstancedMesh extends Mesh {\n static type = 'instanced-mesh'\n static get OPTIONS() { return [...DRAWABLE_OPTIONS, 'count', 'instances', 'instanceMatrices', 'instanceColors', 'labels'] }\n\n /** How many instances are drawn (at most the count it was created with). */\n count = 0\n /** A 4x4 matrix per instance. @type {Float32Array} */\n instanceMatrices\n /** Linear rgb per instance, or null until a colour is set. @type {Float32Array | null} */\n instanceColors = null\n /** @internal Bumped when instance data changes, so renderers re-upload. */\n version = 0\n /** A label per instance from its row of data - or a list of them, several per instance. @type {ReturnType<typeof instanceLabels>} */\n labels = null\n\n /**\n * @param {DrawableOptions & { count?: number, instances?: InstanceOptions[], instanceMatrices?: ArrayLike<number>,\n * instanceColors?: ArrayLike<number>, labels?: InstanceLabels | InstanceLabels[] | null }} options count defaults to the number\n * of instances or rows of data; instanceMatrices/instanceColors are raw data, as toJSON() writes\n */\n constructor(options) {\n super(options)\n this.labels = instanceLabels('InstancedMesh', options.labels)\n const count = options.count ?? options.instances?.length ?? (Array.isArray(options.data) ? options.data.length : undefined)\n if (!Number.isInteger(count) || count < 0) fail('InstancedMesh', `'count' must be a whole number, got ${describe(count)}`)\n this.count = count\n this.instanceMatrices = new Float32Array(count * 16)\n // identity matrices: just the diagonal, written straight in\n const m = this.instanceMatrices\n for (let o = 0; o < m.length; o += 16) m[o] = m[o + 5] = m[o + 10] = m[o + 15] = 1\n options.instances?.forEach((inst, i) => this.setInstance(i, inst))\n if (options.instanceMatrices) {\n if (options.instanceMatrices.length !== count * 16) fail('InstancedMesh', `'instanceMatrices' needs ${count * 16} numbers (16 per instance)`)\n this.instanceMatrices.set(options.instanceMatrices)\n }\n if (options.instanceColors) {\n if (options.instanceColors.length !== count * 3) fail('InstancedMesh', `'instanceColors' needs ${count * 3} numbers (linear rgb per instance)`)\n this.instanceColors = Float32Array.from(options.instanceColors)\n }\n }\n\n /**\n * Set an instance's transform and optional colour. Unset transform parts default to identity.\n * @param {number} i\n * @param {InstanceOptions} options\n * @returns {this}\n */\n setInstance(i, options) {\n this.#checkIndex(i)\n for (const key in options) {\n if (!INSTANCE_OPTIONS.has(key)) fail('InstancedMesh', `unknown instance option '${key}' - expected position, rotation, quaternion, scale or color`)\n }\n const { position, scale, quaternion: q } = scratch\n if (options.position !== undefined) position.copy(options.position, 'InstancedMesh')\n else position.set(0, 0, 0)\n if (options.scale !== undefined) {\n if (typeof options.scale === 'number') scale.set(options.scale, options.scale, options.scale)\n else scale.copy(options.scale, 'InstancedMesh')\n } else scale.set(1, 1, 1)\n q.set(0, 0, 0, 1)\n if (options.quaternion) q.copy(options.quaternion, 'InstancedMesh').normalize()\n else if (options.rotation) {\n const r = options.rotation instanceof Euler ? options.rotation : scratch.rotation.copy(/** @type {any} */ (options.rotation), 'InstancedMesh')\n q.setFromEuler(r.x, r.y, r.z)\n }\n mat4.fromRotationTranslationScale(this.instanceMatrices.subarray(i * 16, i * 16 + 16), q, position, scale)\n if (options.color !== undefined) this.#setColor(i, options.color)\n this.version++\n return this\n }\n\n /**\n * Say instanceMatrices or instanceColors were written directly - the fast path for large data:\n * write the arrays (16 numbers a matrix, column-major; linear rgb), then call this once.\n *\n * const m = bars.instanceMatrices\n * for (let i = 0; i < n; i++) m[i * 16 + 5] = heights[i] // y scale\n * bars.needsUpdate()\n * @returns {this}\n */\n needsUpdate() {\n this.version++\n return this\n }\n\n /**\n * Set just an instance's colour, leaving its transform alone - for highlighting a picked instance.\n * @param {number} i\n * @param {ColorInput} color multiplies the material colour\n * @returns {this}\n */\n setColor(i, color) {\n this.#checkIndex(i)\n this.#setColor(i, color)\n this.version++\n return this\n }\n\n /** @param {number} i */\n #checkIndex(i) {\n if (!Number.isInteger(i) || i < 0 || i >= this.instanceMatrices.length / 16) {\n fail('InstancedMesh', `instance ${describe(i)} is out of range 0-${this.instanceMatrices.length / 16 - 1}`)\n }\n }\n\n /** @param {number} i @param {ColorInput} color */\n #setColor(i, color) {\n if (!this.instanceColors) this.instanceColors = new Float32Array(this.instanceMatrices.length / 16 * 3).fill(1)\n this.instanceColors.set(SCRATCH_COLOR.set(color, 'InstancedMesh'), i * 3)\n }\n\n /** @internal @param {Box3} box */\n expandBounds(box) {\n this.eachInstanceBox((x0, y0, z0, x1, y1, z1) => {\n box.expandByXYZ(x0, y0, z0)\n box.expandByXYZ(x1, y1, z1)\n })\n return box\n }\n\n /**\n * @internal Each instance's world box, as its low and high corners - for fitting a view round the\n * instances themselves rather than the box round them all.\n * @param {(x0: number, y0: number, z0: number, x1: number, y1: number, z1: number) => void} fn\n */\n eachInstanceBox(fn) {\n if (!this.count || !this.geometry.vertexCount) return\n const local = this.geometry.bounds\n // each instance's box from the geometry's centre and half size: the centre moves with the\n // matrix, and the half size grows by the matrix's absolute values - no allocation per instance\n const cx = (local.min[0] + local.max[0]) / 2, cy = (local.min[1] + local.max[1]) / 2, cz = (local.min[2] + local.max[2]) / 2\n const ex = (local.max[0] - local.min[0]) / 2, ey = (local.max[1] - local.min[1]) / 2, ez = (local.max[2] - local.min[2]) / 2\n const w = this.worldMatrix, im = this.instanceMatrices, m = scratchMatrix\n for (let i = 0; i < this.count; i++) {\n if (hiddenInstance(im, i)) continue\n mat4.multiply(m, w, im.subarray(i * 16, i * 16 + 16))\n const x = m[0] * cx + m[4] * cy + m[8] * cz + m[12]\n const y = m[1] * cx + m[5] * cy + m[9] * cz + m[13]\n const z = m[2] * cx + m[6] * cy + m[10] * cz + m[14]\n const hx = Math.abs(m[0]) * ex + Math.abs(m[4]) * ey + Math.abs(m[8]) * ez\n const hy = Math.abs(m[1]) * ex + Math.abs(m[5]) * ey + Math.abs(m[9]) * ez\n const hz = Math.abs(m[2]) * ex + Math.abs(m[6]) * ey + Math.abs(m[10]) * ez\n fn(x - hx, y - hy, z - hz, x + hx, y + hy, z + hz)\n }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), count: this.count, labels: this.labels }\n }\n\n clone(options) {\n const copy = super.clone(options)\n copy.instanceMatrices.set(this.instanceMatrices)\n if (this.instanceColors) copy.instanceColors = this.instanceColors.slice()\n return copy\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), count: this.count, instanceMatrices: Array.from(this.instanceMatrices),\n ...(this.instanceColors ? { instanceColors: Array.from(this.instanceColors) } : {}) }\n }\n}\n\n/** Each vertex drawn as a square point sprite: star fields, particles, scatter plots. */\nexport class Points extends Drawable {\n static type = 'points'\n static get OPTIONS() { return [...DRAWABLE_OPTIONS, 'labels', 'sort'] }\n\n /** A label per point from its row of data - or a list of them, several per point. @type {ReturnType<typeof instanceLabels>} */\n labels = null\n /**\n * Draw the points back to front, furthest first, each frame - for soft points that cover what is\n * behind them (smoke, with blending 'normal'), which then layer the right way round. Drawn as squares.\n */\n sort = false\n\n /** @param {DrawableOptions & { labels?: InstanceLabels | InstanceLabels[] | null, sort?: boolean }} options */\n constructor(options) {\n super(options)\n this.labels = instanceLabels(this.constructor.name, options?.labels)\n if (options?.sort !== undefined) {\n if (typeof options.sort !== 'boolean') fail(this.constructor.name, `'sort' is true or false, got ${describe(options.sort)}`)\n this.sort = options.sort\n }\n }\n\n /**\n * @internal Drawn as squares, one a point, rather than as GL points: when the geometry gives each\n * point its own size, opacity or angle, or the points are sorted. Squares can be any size and stay\n * whole at the edge of the view.\n */\n get drawsSprites() {\n const g = this.geometry\n return this.sort || !!(g.sizes || g.opacities || g.angles)\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), labels: this.labels, sort: this.sort }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.sort ? { sort: true } : {}) }\n }\n\n /** @returns {'points'} */\n get drawMode() {\n return 'points'\n }\n}\n\nconst ARROWS = ['none', 'start', 'end', 'both']\n\n/**\n * @typedef {DrawableOptions & { arrows?: 'none' | 'start' | 'end' | 'both', arrowSize?: number }} LinesOptions\n */\n\n/**\n * Line segments: indices (or consecutive vertices) in pairs. Width is in pixels and works on\n * every platform. edges(geometry) makes a wireframe of any geometry. Segments each starting where\n * the one before ended make a chain - a polyline - which dashes run on along and arrowheads finish.\n */\nexport class Lines extends Drawable {\n static type = 'lines'\n static get OPTIONS() { return [...DRAWABLE_OPTIONS, 'arrows', 'arrowSize'] }\n\n /** Arrowheads at the ends of each chain: at its 'start', its 'end', 'both' or 'none'. @type {'none' | 'start' | 'end' | 'both'} */\n arrows = 'none'\n /** Arrowhead length in pixels; 0 sizes them from the material's width. */\n arrowSize = 0\n\n /** @param {LinesOptions} options */\n constructor(options) {\n super(options)\n if (options?.arrows !== undefined) this.arrows = /** @type {any} */ (checkOneOf('Lines', 'arrows', options.arrows, ARROWS))\n if (options?.arrowSize !== undefined) this.arrowSize = Math.max(0, checkNumber('Lines', 'arrowSize', options.arrowSize))\n }\n\n /** @internal Which ends get arrowheads, for the shader: 1 the start, 2 the end. */\n get arrowBits() {\n return ARROWS.indexOf(this.arrows)\n }\n\n /** @internal An arrowhead's length in pixels, before the pixel ratio. @param {number} width */\n arrowPixels(width) {\n return this.arrowSize || 6 + width * 3\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), arrows: this.arrows, arrowSize: this.arrowSize }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.arrows !== 'none' ? { arrows: this.arrows } : {}), ...(this.arrowSize ? { arrowSize: this.arrowSize } : {}) }\n }\n\n /** @returns {'lines'} */\n get drawMode() {\n return 'lines'\n }\n\n /** @internal */\n checkGeometry() {\n const n = this.geometry.elementCount\n if (n % 2 !== 0) fail('Lines', `geometry has ${n} ${this.geometry.indices ? 'indices' : 'vertices'} - segments need them in pairs`)\n }\n}\n\n/**\n * @typedef {NodeOptions & LabelPlacement & { text: string | number }} LabelOptions\n */\n\n/**\n * HTML text pinned to a 3D position: crisp at any pixel ratio and styleable with CSS. Hidden when\n * behind the camera or invisible.\n */\nexport class Label extends Node {\n static type = 'label'\n static get OPTIONS() { return [...NODE_OPTIONS, 'text', ...PLACEMENT_OPTIONS] }\n static get HINTS() { return LABEL_HINTS }\n\n text = ''\n /** CSS class(es) for the label element. */\n className = ''\n /** Where the label goes relative to its point. @type {LabelPlace} */\n place = 'center'\n /** Extra shift in CSS pixels, +y down. @type {[number, number]} */\n offset = [0, 0]\n /** When labels overlap, the higher priority stays. */\n priority = 0\n /** When covered by a higher-priority label (or geometry, with occlude): 'hide' drops it, 'dim' fades it, 'show' always shows it. @type {'hide' | 'dim' | 'show'} */\n overlap = 'hide'\n /** The label counts as covered when geometry is in front of its point. */\n occlude = false\n /** A line from the label's point to the label, for callouts. */\n leader = false\n /** Set at the view's left or right edge, level with its point, or null for by its point. @type {'left' | 'right' | null} */\n edge = null\n /** Shown only when zoomed in this far: CSS pixels to one world unit at its point; 0 for always. */\n minScale = 0\n\n /** @param {LabelOptions} options */\n constructor(options) {\n super(options)\n if (typeof options?.text !== 'string' && typeof options?.text !== 'number') {\n fail('Label', `'text' is required, got ${describe(options?.text)}`)\n }\n this.text = String(options.text)\n Object.assign(this, placement('Label', options))\n }\n\n /** @internal Lets renderers spot labels without importing this class. */\n get isLabel() {\n return true\n }\n\n /** @internal A label counts as the point it is pinned to, so framing leaves room for axis ticks and titles. @param {Box3} box */\n expandBounds(box) {\n return box.expandByPoint(this.worldPosition)\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), text: this.text, className: this.className, place: this.place,\n offset: [...this.offset], priority: this.priority, overlap: this.overlap, occlude: this.occlude, leader: this.leader, edge: this.edge,\n minScale: this.minScale }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = { text: this.text }\n if (this.className) json.className = this.className\n if (this.place !== 'center') json.place = this.place\n if (this.offset[0] || this.offset[1]) json.offset = [...this.offset]\n if (this.priority) json.priority = this.priority\n if (this.overlap !== 'hide') json.overlap = this.overlap\n if (this.occlude) json.occlude = true\n if (this.leader) json.leader = true\n if (this.edge) json.edge = this.edge\n if (this.minScale) json.minScale = this.minScale\n return json\n }\n}\n","// The renderer contract: what to draw this frame, as plain data. The scene never talks to WebGL -\n// a renderer draws a FrameDescription, so renderers are replaceable and frames testable without a GPU.\nimport { Mat4 } from './value/Mat4.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { Box3 } from './value/Box3.js'\nimport { warnOnce } from './validate.js'\nimport { fitPointShadow, fitShadow, fitSpotShadow, SPOT_TILES } from './shadow.js'\nimport { worldPlane } from './clip.js'\nimport { hiddenInstance } from './scene/drawables.js'\n\n/** @import { Scene } from './scene/Scene.js' */\n/** @import { Camera } from './scene/cameras.js' */\n/** @import { Node } from './scene/Node.js' */\n/** @import { Color } from './value/Color.js' */\n/** @import { Texture } from './material/Texture.js' */\n/** @import { Geometry } from './geometry/Geometry.js' */\n/** @import { Material } from './material/Material.js' */\n/** @import { Drawable, InstancedMesh, Label, LabelPlacement } from './scene/drawables.js' */\n/** @import { Light, HemisphereLight, DirectionalLight, PointLight, SpotLight } from './scene/lights.js' */\n\n// Nodes are told apart by markers (isDrawable, isLabel, lightKind) rather than instanceof, so\n// collecting a frame doesn't pull every node class into an app's bundle.\n\n/** Per-scene light limits for the WebGL 2 renderer; extras are dropped with a warning. */\nexport const LIGHT_LIMITS = { punctual: 4, directional: 2 }\n\n/**\n * @typedef {object} FrameLight\n * @property {'ambient' | 'hemisphere' | 'directional' | 'point' | 'spot'} kind\n * @property {Node} node\n * @property {Color} color\n * @property {number} intensity\n * @property {Color} [ground] hemisphere\n * @property {Vec3} [position] point, spot (world)\n * @property {Vec3} [direction] directional, spot (world, the way the light travels)\n * @property {number} [range] point, spot (0 = unlimited)\n * @property {number} [angle] spot\n * @property {number} [penumbra] spot\n * @property {boolean} [castShadow] directional, spot, point\n * @property {number} [shadowTile] spot: which spot shadow is its, or -1\n */\n\n/**\n * The section plane cutting a drawable, from the nearest clip above it.\n * @typedef {object} FrameClip\n * @property {Float32Array} plane [nx, ny, nz, d] in world space, unit normal: cut away where n.p + d > 0\n * @property {Color | null} cap fill colour for cut faces (linear), or null for none\n */\n\n/**\n * A subtree to outline: the meshes in it, drawn together, so the line runs round their joint silhouette.\n * @typedef {object} FrameOutline\n * @property {Color} color linear\n * @property {number} width CSS pixels\n * @property {DrawItem[]} items\n */\n\n/**\n * A section plane's cap: the cut faces of the solids under one clip, filled in its colour. The\n * renderer finds where the plane passes through solid by counting each pixel's faces into the\n * stencil buffer, then fills those pixels with the plane - drawn where it is, so nothing in the\n * same plane fights it, and what is inside the solids stays hidden.\n * @typedef {object} FrameCap\n * @property {Float32Array} plane [nx, ny, nz, d], as the clip's\n * @property {Color} color linear\n * @property {DrawItem[]} items the opaque meshes under the clip, as drawn\n * @property {Vec3} center a point on the plane in the middle of the cut\n * @property {number} radius how far from center the cut reaches, at most\n */\n\n/**\n * @typedef {object} DrawItem\n * @property {Drawable} node\n * @property {Geometry} geometry\n * @property {Material} material\n * @property {Mat4} worldMatrix\n * @property {InstancedMesh | null} instances\n * @property {number} depth view-space distance of the bounds centre, for sorting\n * @property {FrameClip | null} clip the plane cutting it, if any\n */\n\n/**\n * @typedef {object} FrameLabel\n * @property {any} key stable identity across frames: the Label node, or a key per instance or point\n * @property {Node} node the Label, or the InstancedMesh or Points it labels\n * @property {number | null} index the instance or point, for labels made from `labels`\n * @property {string} text\n * @property {Required<LabelPlacement>} style\n * @property {Vec3} position world\n * @property {[number, number]} ndc [x, y] in -1..1\n * @property {number} depth\n * @property {boolean} visible in front of the camera and inside the view\n * @property {number} scale how far zoomed in at the point: half the view's height, in world units, is 1 / scale -\n * the layer turns it into pixels to one world unit, for minScale\n */\n\n/**\n * The shadow-casting directional light's view of the scene: what to draw into its depth map.\n * @typedef {object} ShadowFrame\n * @property {FrameLight} light\n * @property {Mat4} viewProjection world to the light's clip space\n * @property {number} texelSize world units per shadow map texel\n * @property {DrawItem[]} casters drawn into the map, whether or not the camera sees them\n */\n\n/**\n * A spot light's view of the scene for its shadow: its tile in the spot shadow map.\n * @typedef {object} SpotShadowFrame\n * @property {FrameLight} light\n * @property {number} tile 0 - 3\n * @property {Mat4} viewProjection world to the light's clip space\n * @property {number} texelAngle a shadow map texel's size at a distance of 1, for the bias\n * @property {DrawItem[]} casters what it draws, culled to the light's view\n */\n\n/**\n * A point light's view of the scene for its shadow: six faces of a cube round it.\n * @typedef {object} PointShadowFrame\n * @property {FrameLight} light\n * @property {{ viewProjection: Mat4, casters: DrawItem[] }[]} faces +X, -X, +Y, -Y, +Z, -Z, each with what it sees\n * @property {number} near\n * @property {number} far\n * @property {number} texelAngle a texel's size at a distance of 1, for the bias\n */\n\n/**\n * The hovered thing to tint: a whole node, or one of its instances or points - or, under a node with\n * highlightWhole, every drawable in that subtree.\n * @typedef {object} FrameHighlight\n * @property {Node} node\n * @property {number | null} index instance (InstancedMesh) or point (Points); null for the whole node\n * @property {Set<Node> | null} [nodes] every drawable tinted, when a highlightWhole subtree is tinted as one\n * @property {Color} color linear\n * @property {number} amount 0-1, how far the colour moves towards it\n */\n\n/**\n * @typedef {object} FrameDescription\n * @property {{ view: Mat4, projection: Mat4, viewProjection: Mat4, position: Vec3, near: number, far: number, camera: Camera }} camera\n * @property {FrameLight[]} lights\n * @property {DrawItem[]} opaque sorted by renderOrder, then material variant, then front to back\n * @property {DrawItem[]} transparent sorted by renderOrder, then back to front\n * @property {FrameLabel[]} labels\n * @property {Color | Texture | null} background\n * @property {Scene['environment']} environment\n * @property {number} environmentIntensity\n * @property {number} backgroundBlur 0-1\n * @property {import('./fog.js').Fog | null} fog distance fog\n * @property {ShadowFrame | null} shadow the shadow-casting light's view, when there is one and something casts\n * @property {SpotShadowFrame[]} spotShadows spot lights' shadows, up to four\n * @property {PointShadowFrame | null} pointShadow a point light's shadow, all round it\n * @property {FrameCap[]} caps section planes' caps to fill, after the opaque pass\n * @property {{ drawn: number, culled: number }} stats\n * @property {FrameHighlight | null} highlight set by the View for hover highlighting\n * @property {any[]} overlays HTML elements carried by the nodes drawn (node.overlay)\n * @property {boolean} interactive some node has a tooltip, highlight or pointer handler\n * @property {boolean} draggable some node has an onDrag handler\n * @property {FrameOutline[]} outlines subtrees to draw an outline round, last of all\n * @property {boolean} tooltips some node has its own tooltip\n */\n\n/**\n * What to draw: everything visible, culled to the camera's view, sorted for drawing. Expects world\n * matrices to be current (scene.update() or scene.updateWorld()); the camera is brought up to date\n * here, since it often isn't in the scene.\n * @param {Scene} scene\n * @param {Camera} camera\n * @returns {FrameDescription}\n */\nexport function collect(scene, camera) {\n camera.updateWorld()\n const view = camera.viewMatrix\n const projection = camera.projectionMatrix\n const viewProjection = new Mat4().multiplyMatrices(projection, view)\n const planes = frustumPlanes(viewProjection)\n\n /** @type {FrameDescription} */\n const frame = {\n camera: { view, projection, viewProjection, position: camera.worldPosition, near: camera.near, far: camera.far, camera },\n lights: [],\n opaque: [],\n transparent: [],\n labels: [],\n background: scene.background,\n environment: scene.environment,\n environmentIntensity: scene.environmentIntensity,\n backgroundBlur: scene.backgroundBlur,\n fog: scene.fog,\n shadow: null,\n spotShadows: [],\n pointShadow: null,\n caps: [],\n stats: { drawn: 0, culled: 0 },\n highlight: null,\n overlays: [],\n interactive: false,\n draggable: false,\n outlines: [],\n tooltips: false,\n }\n let punctual = 0, directional = 0\n // shadows: what casts (seen or not - a shadow can fall into view from off screen) and what\n // receives; only looked at further when a light casts\n /** @type {[any, FrameClip | null][]} */\n const casters = []\n /** @type {any[]} */\n const receivers = []\n // the solids under each capped clip\n /** @type {Map<FrameClip, DrawItem[]>} */\n const capped = new Map()\n\n /**\n * @param {any} node @param {FrameClip | null} clip the plane cutting this subtree, from above\n * @param {FrameOutline | null} outline the outline drawn round this subtree, from above\n */\n const visit = (node, clip, outline) => {\n // per-camera visibility decides what this frame draws, without touching the scene\n if (!node.shownTo(camera)) return\n // the nearest clip cuts this subtree\n if (node.clip) clip = { plane: worldPlane(node), cap: node.clip.cap }\n // an outline goes round everything under the node that asks for it\n if (node.outline) {\n outline = { color: node.outline.color, width: node.outline.width, items: [] }\n frame.outlines.push(outline)\n }\n if (node.overlay) frame.overlays.push(node.overlay)\n if (node.onDrag) frame.interactive = frame.draggable = true\n if (node.tooltip) frame.interactive = frame.tooltips = true\n else if (node.highlight || node.handlersFor('hover').length || node.handlersFor('click').length) frame.interactive = true\n if (node.isDrawable) {\n if (node.castShadow && node.drawMode !== 'points' && node.drawMode !== 'lines') casters.push([node, clip])\n if (node.receiveShadow) receivers.push(node)\n const item = drawItem(node, view, planes, clip)\n if (item) {\n // point sprites with a map nearly always have soft alpha edges, so they blend too\n const blended = node.material.transparent || (node.drawMode === 'points' && node.material.map)\n ;(blended ? frame.transparent : frame.opaque).push(item)\n if (outline && node.drawMode === 'triangles') outline.items.push(item)\n if (item.clip?.cap && !blended) {\n const solids = capped.get(item.clip)\n if (solids) solids.push(item)\n else capped.set(item.clip, [item])\n }\n frame.stats.drawn++\n if (node.labels) instanceLabels(node, viewProjection, view, projection[5], frame.labels)\n } else {\n frame.stats.culled++\n }\n } else if (node.isLabel) {\n const position = node.worldPosition\n frame.labels.push({ key: node, node, index: null, text: node.text, style: node, position, ...project(position, viewProjection, view, projection[5]) })\n } else if (node.lightKind) {\n addLight(/** @type {Light} */ (node))\n }\n for (const child of node.children) visit(child, clip, outline)\n }\n\n /** @param {any} node */\n const addLight = (node) => {\n const kind = node.lightKind\n if (kind === 'ambient') {\n frame.lights.push({ kind: 'ambient', node, color: node.color, intensity: node.intensity })\n } else if (kind === 'hemisphere') {\n frame.lights.push({ kind: 'hemisphere', node, color: node.sky, ground: node.ground, intensity: node.intensity })\n } else if (kind === 'directional') {\n if (++directional > LIGHT_LIMITS.directional) {\n warnOnce(scene, `more than ${LIGHT_LIMITS.directional} directional lights - the extras are ignored; use scene.environment for more light`)\n } else {\n frame.lights.push({ kind: 'directional', node, color: node.color, intensity: node.intensity, direction: node.worldDirection, castShadow: node.castShadow })\n }\n } else {\n if (++punctual > LIGHT_LIMITS.punctual) {\n warnOnce(scene, `more than ${LIGHT_LIMITS.punctual} point and spot lights - the extras are ignored`)\n } else if (kind === 'spot') {\n frame.lights.push({ kind: 'spot', node, color: node.color, intensity: node.intensity, position: node.worldPosition,\n direction: node.worldDirection, range: node.range, angle: node.angle, penumbra: node.penumbra, castShadow: node.castShadow, shadowTile: -1 })\n } else {\n frame.lights.push({ kind: 'point', node, color: node.color, intensity: node.intensity, position: node.worldPosition, range: node.range, castShadow: node.castShadow })\n }\n }\n }\n visit(scene, null, null)\n frame.outlines = frame.outlines.filter((o) => o.items.length)\n for (const [clip, items] of capped) frame.caps.push(capOf(clip, items))\n\n // one shadow map, for the first directional light that casts; it goes first, so the shader\n // knows which light the map belongs to\n const sun = frame.lights.findIndex((l) => l.kind === 'directional' && l.castShadow)\n const spots = frame.lights.filter((l) => l.kind === 'spot' && l.castShadow)\n const points = frame.lights.filter((l) => l.kind === 'point' && l.castShadow)\n const items = sun >= 0 || spots.length || points.length ? /** @type {DrawItem[]} */ (casters.map(([n, clip]) => drawItem(n, view, null, clip)).filter(Boolean)) : []\n if (spots.length > SPOT_TILES) warnOnce(scene, `more than ${SPOT_TILES} spot lights cast shadows - the extras don't`)\n if (points.length > 1) warnOnce(scene, 'more than one point light casts shadows - only the first does')\n if (items.length && points.length) {\n const light = points[0]\n const boxes = items.map((c) => c.node.expandBounds(new Box3()))\n const fit = fitPointShadow(/** @type {Vec3} */ (light.position), light.range ?? 0, boxes, receivers.map((n) => n.expandBounds(new Box3())))\n if (fit) {\n // each face draws only what it can see\n const faces = fit.viewProjections.map((viewProjection) => {\n const planes = frustumPlanes(viewProjection)\n return { viewProjection, casters: items.filter((_, i) => sphereInFrustum(planes, boxes[i].getCenter(), boxes[i].getRadius())) }\n })\n frame.pointShadow = { light, faces, near: fit.near, far: fit.far, texelAngle: fit.texelAngle }\n }\n }\n if (items.length && spots.length) {\n const boxes = items.map((c) => c.node.expandBounds(new Box3()))\n const receiving = receivers.map((n) => n.expandBounds(new Box3()))\n for (const light of spots.slice(0, SPOT_TILES)) {\n const at = /** @type {Vec3} */ (light.position)\n // the light's own fitting - a lamp round it - doesn't shadow it\n const own = boxes.map((b) => b.containsPoint(at))\n const fit = fitSpotShadow(at, /** @type {Vec3} */ (light.direction), /** @type {number} */ (light.angle), light.range ?? 0, boxes.filter((_, i) => !own[i]), receiving)\n if (!fit) continue\n const planes = frustumPlanes(fit.viewProjection)\n const seen = items.filter((item, i) => {\n if (own[i]) return false\n const box = boxes[i]\n return sphereInFrustum(planes, box.getCenter(), box.getRadius())\n })\n light.shadowTile = frame.spotShadows.length\n frame.spotShadows.push({ light, tile: light.shadowTile, viewProjection: fit.viewProjection, texelAngle: fit.texelAngle, casters: seen })\n }\n }\n if (items.length && sun >= 0) {\n const light = frame.lights[sun]\n const bounds = (/** @type {any} */ n) => n.expandBounds(new Box3())\n const fit = fitShadow(/** @type {Vec3} */ (light.direction), items.map((c) => bounds(c.node)), receivers.map(bounds), undefined, /** @type {any} */ (light.node).shadowBounds)\n if (fit) {\n frame.lights.splice(sun, 1)\n frame.lights.unshift(light)\n frame.shadow = { light, ...fit, casters: items }\n }\n }\n\n // opaque: front to back lets the depth test reject hidden pixels early; grouping by material\n // variant keeps shader switches down\n frame.opaque.sort((x, y) => x.node.renderOrder - y.node.renderOrder ||\n (x.material.variant < y.material.variant ? -1 : x.material.variant > y.material.variant ? 1 : 0) ||\n x.depth - y.depth)\n // transparent: back to front so blending composes correctly\n frame.transparent.sort((x, y) => x.node.renderOrder - y.node.renderOrder || y.depth - x.depth)\n return frame\n}\n\n/**\n * @param {Drawable} node @param {Mat4} view @param {Float32Array[] | null} planes null: no culling\n * @param {FrameClip | null} clip the plane cutting it\n * @returns {DrawItem | null} null when culled, or cut away whole\n */\nfunction drawItem(node, view, planes, clip) {\n const { geometry, material, worldMatrix } = node\n const instances = 'instanceMatrices' in node ? /** @type {InstancedMesh} */ (node) : null\n if (instances && instances.count === 0) return null\n if (!geometry.vertexCount) return null\n\n const box = geometry.bounds\n const center = box.getCenter().applyMatrix4(worldMatrix)\n const scale = Math.max(Math.hypot(worldMatrix[0], worldMatrix[1], worldMatrix[2]),\n Math.hypot(worldMatrix[4], worldMatrix[5], worldMatrix[6]), Math.hypot(worldMatrix[8], worldMatrix[9], worldMatrix[10]))\n // instanced meshes spread their copies anywhere, so they aren't culled as a whole\n if (planes && node.frustumCulled && !instances && !sphereInFrustum(planes, center, box.getRadius() * scale)) return null\n // all of it on the cut-away side of a clip - points and lines aren't cut, so they stay\n const cuts = clip && node.drawMode === 'triangles' ? clip : null\n if (cuts && !instances) {\n const p = cuts.plane\n if (p[0] * center[0] + p[1] * center[1] + p[2] * center[2] + p[3] > box.getRadius() * scale) return null\n }\n\n // distance in front of the camera, along its view direction\n const depth = -(view[2] * center[0] + view[6] * center[1] + view[10] * center[2] + view[14])\n return { node, geometry, material, worldMatrix, instances, depth, clip: cuts }\n}\n\n/**\n * Where a clip's cap goes: the middle of its solids' bounds, brought onto the plane, and how far\n * the cut can reach from there.\n * @param {FrameClip} clip @param {DrawItem[]} items\n * @returns {FrameCap}\n */\nfunction capOf(clip, items) {\n const box = new Box3()\n for (const item of items) item.node.expandBounds(box)\n const c = box.getCenter(), p = clip.plane\n const off = p[0] * c[0] + p[1] * c[1] + p[2] * c[2] + p[3]\n const center = new Vec3(c[0] - p[0] * off, c[1] - p[1] * off, c[2] - p[2] * off)\n return { plane: clip.plane, color: /** @type {Color} */ (clip.cap), items, center, radius: box.getRadius() }\n}\n\n// a stable key per labelled node, so label elements survive from frame to frame\n/** @type {WeakMap<object, number>} */\nconst ids = new WeakMap()\nlet nextId = 1\n\n/**\n * Labels for every instance or point that has text, from the node's `labels` option.\n * @param {any} node InstancedMesh or Points @param {Mat4} viewProjection @param {Mat4} view\n * @param {number} yScale the projection's vertical scale @param {FrameLabel[]} out\n */\nfunction instanceLabels(node, viewProjection, view, yScale, out) {\n // several labels per instance: the first keeps the plain key, so a single set's labels don't change identity\n if (Array.isArray(node.labels)) {\n node.labels.forEach((labels, layer) => instanceLabelSet(node, labels, layer, viewProjection, view, yScale, out))\n } else instanceLabelSet(node, node.labels, 0, viewProjection, view, yScale, out)\n}\n\n/**\n * @param {any} node @param {any} labels one set of instance labels @param {number} layer its place in the list\n * @param {Mat4} viewProjection @param {Mat4} view @param {number} yScale @param {FrameLabel[]} out\n */\nfunction instanceLabelSet(node, labels, layer, viewProjection, view, yScale, out) {\n const { worldMatrix: w } = node\n let id = ids.get(node)\n if (id === undefined) ids.set(node, id = nextId++)\n const instanced = 'instanceMatrices' in node\n const n = instanced ? node.count : node.geometry.drawnVertices\n let px = 0, py = 0, pz = 0\n if (instanced) {\n // where on each instance: the top centre or the centre of its geometry\n const box = node.geometry.bounds, c = box.getCenter()\n px = c[0]; py = labels.at === 'top' ? box.max[1] : c[1]; pz = c[2]\n }\n const data = Array.isArray(node.data) ? node.data : null\n const byRow = typeof labels.priority === 'function'\n for (let i = 0; i < n; i++) {\n // an instance scaled to nothing is hidden, and so is its label\n if (instanced && hiddenInstance(node.instanceMatrices, i)) continue\n const row = data ? data[i] : null\n const text = labels.text(row, i)\n if (text === null || text === undefined || text === '') continue\n let x, y, z\n if (instanced) {\n const m = node.instanceMatrices, o = i * 16\n x = m[o] * px + m[o + 4] * py + m[o + 8] * pz + m[o + 12]\n y = m[o + 1] * px + m[o + 5] * py + m[o + 9] * pz + m[o + 13]\n z = m[o + 2] * px + m[o + 6] * py + m[o + 10] * pz + m[o + 14]\n } else {\n const p = node.geometry.positions\n x = p[i * 3]; y = p[i * 3 + 1]; z = p[i * 3 + 2]\n }\n const position = new Vec3(\n w[0] * x + w[4] * y + w[8] * z + w[12],\n w[1] * x + w[5] * y + w[9] * z + w[13],\n w[2] * x + w[6] * y + w[10] * z + w[14])\n const style = byRow ? { ...labels, priority: labels.priority(row, i) } : labels\n out.push({ key: layer ? `${id}:${i}:${layer}` : `${id}:${i}`, node, index: i, text: String(text), style, position, ...project(position, viewProjection, view, yScale) })\n }\n}\n\n/**\n * Where a world position lands in normalised device coordinates (x, y and z, -1 to 1), and whether it\n * is in view: inside the edges, and between the near and far planes. Labels and view.project() both\n * place things with it.\n * @param {ArrayLike<number>} position @param {ArrayLike<number>} viewProjection\n * @returns {{ ndc: [number, number, number], visible: boolean }}\n */\nexport function toScreen(position, viewProjection) {\n const m = viewProjection\n const x = m[0] * position[0] + m[4] * position[1] + m[8] * position[2] + m[12]\n const y = m[1] * position[0] + m[5] * position[1] + m[9] * position[2] + m[13]\n const z = m[2] * position[0] + m[6] * position[1] + m[10] * position[2] + m[14]\n const w = m[3] * position[0] + m[7] * position[1] + m[11] * position[2] + m[15]\n const ndc = /** @type {[number, number, number]} */ ([x / w, y / w, z / w])\n return { ndc, visible: w > 0 && Math.abs(ndc[0]) <= 1 && Math.abs(ndc[1]) <= 1 && Math.abs(ndc[2]) <= 1 }\n}\n\n/**\n * A label's place on screen, and how far in front of the camera it is - along the view, in world\n * units, for both kinds of camera (an orthographic one's clip w is always 1).\n * @param {Vec3} position @param {Mat4} viewProjection @param {Mat4} view\n */\nfunction project(position, viewProjection, view, yScale) {\n const { ndc, visible } = toScreen(position, viewProjection)\n const depth = -(view[2] * position[0] + view[6] * position[1] + view[10] * position[2] + view[14])\n // clip w at the point: its depth for a perspective camera, 1 for an orthographic one\n const m = viewProjection\n const w = m[3] * position[0] + m[7] * position[1] + m[11] * position[2] + m[15]\n return { ndc: /** @type {[number, number]} */ ([ndc[0], ndc[1]]), depth, visible, scale: w > 0 ? yScale / w : 0 }\n}\n\n// The six planes (a, b, c, d with the normal pointing inwards) of a view-projection matrix.\n/** @param {Float32Array} m @returns {Float32Array[]} */\nfunction frustumPlanes(m) {\n const rows = (i) => [m[i], m[4 + i], m[8 + i], m[12 + i]]\n const r0 = rows(0), r1 = rows(1), r2 = rows(2), r3 = rows(3)\n return [\n [r3[0] + r0[0], r3[1] + r0[1], r3[2] + r0[2], r3[3] + r0[3]],\n [r3[0] - r0[0], r3[1] - r0[1], r3[2] - r0[2], r3[3] - r0[3]],\n [r3[0] + r1[0], r3[1] + r1[1], r3[2] + r1[2], r3[3] + r1[3]],\n [r3[0] - r1[0], r3[1] - r1[1], r3[2] - r1[2], r3[3] - r1[3]],\n [r3[0] + r2[0], r3[1] + r2[1], r3[2] + r2[2], r3[3] + r2[3]],\n [r3[0] - r2[0], r3[1] - r2[1], r3[2] - r2[2], r3[3] - r2[3]],\n ].map((p) => {\n const len = Math.hypot(p[0], p[1], p[2]) || 1\n return new Float32Array([p[0] / len, p[1] / len, p[2] / len, p[3] / len])\n })\n}\n\n/** @param {Float32Array[]} planes @param {ArrayLike<number>} c @param {number} radius */\nfunction sphereInFrustum(planes, c, radius) {\n for (const p of planes) {\n if (p[0] * c[0] + p[1] * c[1] + p[2] * c[2] + p[3] < -radius) return false\n }\n return true\n}\n\n/**\n * A renderer that records frames instead of drawing them - for tests, doc-tests and server-side\n * checks. Same render() contract as the WebGL renderer.\n */\nexport class NullRenderer {\n /** @type {FrameDescription | null} */\n lastFrame = null\n frameCount = 0\n\n /**\n * Bring world matrices up to date and record what would be drawn. Doesn't run update handlers -\n * the View's loop (or your own) does that with scene.update(dt, t).\n * @param {Scene} scene @param {Camera} camera\n * @returns {FrameDescription}\n */\n render(scene, camera) {\n scene.updateWorldTree()\n return this.renderFrame(collect(scene, camera))\n }\n\n /** @internal @param {FrameDescription} frame @returns {FrameDescription} */\n renderFrame(frame) {\n this.lastFrame = frame\n this.frameCount++\n return frame\n }\n\n dispose() {}\n}\n\n","// Label placement and overlap resolution, as plain arithmetic on boxes - no DOM, so it is testable\n// and the label layer stays a thin writer of styles.\n\n/** @import { LabelPlace } from './scene/drawables.js' */\n\n// gap between a point and a label placed beside it, in CSS pixels\nconst GAP = 6\n// how far labels set at an edge of the view sit in from it, in CSS pixels\nconst EDGE = 16\n// grid cell size for finding neighbours quickly\nconst CELL = 64\n// how far two labels may run into each other before one gives way: a label newly showing\n// needs to be mostly clear; one already showing holds on through more, so labels don't flicker\n// in and out as the view moves\nconst NEW_OVERLAP = 0.2\nconst KEEP_OVERLAP = 0.5\n\n/**\n * Top-left corner of a label box placed relative to its point.\n * @param {number} x @param {number} y the point, in pixels\n * @param {number} width @param {number} height the label's size\n * @param {LabelPlace} place where the label goes relative to the point\n * @param {[number, number]} offset extra shift in pixels\n * @param {'left' | 'right' | null} [edge] set at that edge of the view instead, level with the point\n * @param {number} [viewWidth] the view's width, for edge: 'right'\n * @returns {[number, number]}\n */\nexport function placeBox(x, y, width, height, place, offset, edge = null, viewWidth = 0) {\n // at an edge of the view, level with the point: offset moves it in from the edge, and up or down\n if (edge) return [edge === 'left' ? EDGE + offset[0] : viewWidth - EDGE - width - offset[0], y - height / 2 + offset[1]]\n let left = x - width / 2, top = y - height / 2\n if (place === 'above') top = y - height - GAP\n else if (place === 'below') top = y + GAP\n else if (place === 'left') left = x - width - GAP\n else if (place === 'right') left = x + GAP\n return [left + offset[0], top + offset[1]]\n}\n\n/**\n * Space out the labels in a column at an edge of the view, so callouts never overlap: in each\n * column they keep the order of their points, top to bottom, at least `gap` apart. Labels that would\n * run into each other move as a group, centred where they wanted to be on average - so each stays\n * as near its point as it can - and the group is kept inside the view. Changes each box's top.\n * @param {{ top: number, height: number, edge?: 'left' | 'right' | null }[]} boxes\n * @param {number} height the view's height\n * @param {number} [gap]\n */\nexport function stackColumns(boxes, height, gap = 4) {\n for (const side of ['left', 'right']) {\n const column = boxes.filter((b) => b.edge === side).sort((a, b) => a.top - b.top)\n /** @type {{ items: typeof column, wants: number[], top: number, height: number }[]} */\n const groups = []\n for (const box of column) {\n let group = { items: [box], wants: [box.top], top: box.top, height: box.height }\n // merge with the group above while they would overlap\n while (groups.length) {\n const above = groups[groups.length - 1]\n if (above.top + above.height + gap <= group.top) break\n groups.pop()\n const items = [...above.items, ...group.items], wants = [...above.wants, ...group.wants]\n let offset = 0, shift = 0\n for (let i = 0; i < items.length; i++) {\n shift += wants[i] - offset\n offset += items[i].height + gap\n }\n const total = offset - gap\n group = { items, wants, top: Math.min(Math.max(shift / items.length, 0), Math.max(0, height - total)), height: total }\n }\n groups.push(group)\n }\n for (const group of groups) {\n let top = group.top\n for (const box of group.items) {\n box.top = top\n top += box.height + gap\n }\n }\n }\n}\n\n/**\n * Line up each column of labels at an edge of the view: every label in it as wide as the widest, the\n * right column's moved in to keep its right side at the edge - so their leaders all start from the\n * same line and none runs under a neighbour. Changes each box's width (and left, on the right).\n * @param {{ left: number, width: number, edge?: 'left' | 'right' | null }[]} boxes\n */\nexport function alignColumns(boxes) {\n for (const side of ['left', 'right']) {\n const column = boxes.filter((b) => b.edge === side)\n const widest = Math.max(0, ...column.map((b) => b.width))\n for (const b of column) {\n if (side === 'right') b.left -= widest - b.width\n b.width = widest\n }\n }\n}\n\n/**\n * Where a leader line from a label's point meets its box: the nearest point of the box, or null\n * when the point is in (or touching) the box and needs no line. A callout in a column at an edge is\n * met at the inner end of its bottom edge, where an underline ends - and always gets its line.\n * @param {number} x @param {number} y the point\n * @param {{ left: number, top: number, width: number, height: number }} box\n * @param {'left' | 'right' | null} [edge]\n * @param {number} [rule] the thickness of its underline (its bottom border), whose middle the line meets\n * @returns {[number, number] | null}\n */\nexport function leaderEnd(x, y, box, edge = null, rule = 0) {\n if (edge) return [edge === 'left' ? box.left + box.width : box.left, box.top + box.height - rule / 2]\n const tx = Math.min(Math.max(x, box.left), box.left + box.width)\n const ty = Math.min(Math.max(y, box.top), box.top + box.height)\n return Math.hypot(tx - x, ty - y) < 2 ? null : [tx, ty]\n}\n\n/**\n * @typedef {object} LabelBox\n * @property {number} left\n * @property {number} top\n * @property {number} width\n * @property {number} height\n * @property {number} priority higher is kept first\n * @property {'hide' | 'dim' | 'show'} overlap what to do when it loses: hide, dim, or never lose\n * @property {number} depth nearer is kept first among equal priorities\n * @property {boolean} [sticky] it was showing last frame, so it holds its place more firmly\n * @property {boolean} [covered] geometry is in front of it, so it loses to every label\n */\n\n/** @typedef {'show' | 'dim' | 'hide'} LabelState */\n\n/**\n * Which labels to show, dim or hide. 'show' labels go first, then higher priorities, then labels\n * already showing, then nearer ones. A label that runs into one already placed by more than it may\n * (20% of its size, or 50% if it was showing last frame) loses: hidden, or dimmed if its\n * overlap is 'dim'. A covered label always loses, unless its overlap is 'show'. Dimmed labels\n * don't block others. Greedy and stable, so the same view always gives the same answer.\n * @param {LabelBox[]} boxes\n * @returns {LabelState[]} by index\n */\nexport function layoutLabels(boxes) {\n const order = boxes.map((_, i) => i).sort((a, b) => {\n const x = boxes[a], y = boxes[b]\n return (y.overlap === 'show' ? 1 : 0) - (x.overlap === 'show' ? 1 : 0) || y.priority - x.priority ||\n (y.sticky ? 1 : 0) - (x.sticky ? 1 : 0) || x.depth - y.depth || a - b\n })\n /** @type {LabelState[]} */\n const states = new Array(boxes.length).fill('hide')\n /** @type {Map<string, LabelBox[]>} */\n const grid = new Map()\n const cells = (b, fn) => {\n const x0 = Math.floor(b.left / CELL), x1 = Math.floor((b.left + b.width) / CELL)\n const y0 = Math.floor(b.top / CELL), y1 = Math.floor((b.top + b.height) / CELL)\n for (let cx = x0; cx <= x1; cx++) for (let cy = y0; cy <= y1; cy++) fn(`${cx},${cy}`)\n }\n // how far two boxes run into each other, as a share of the smaller size on the axis that parts\n // them soonest - not shared area, which stays small for labels staggered diagonally along an\n // axis even when their text meets\n const shared = (a, b) => {\n const w = Math.min(a.left + a.width, b.left + b.width) - Math.max(a.left, b.left)\n const h = Math.min(a.top + a.height, b.top + b.height) - Math.max(a.top, b.top)\n if (w <= 0 || h <= 0) return 0\n return Math.min(w / Math.max(1, Math.min(a.width, b.width)), h / Math.max(1, Math.min(a.height, b.height)))\n }\n\n for (const i of order) {\n const box = boxes[i]\n if (box.overlap !== 'show') {\n const allowed = box.sticky ? KEEP_OVERLAP : NEW_OVERLAP\n let blocked = !!box.covered\n cells(box, (key) => { if (!blocked) blocked = (grid.get(key) ?? []).some((other) => shared(box, other) > allowed) })\n if (blocked) {\n states[i] = box.overlap === 'dim' ? 'dim' : 'hide'\n continue\n }\n }\n states[i] = 'show'\n cells(box, (key) => {\n let list = grid.get(key)\n if (!list) grid.set(key, list = [])\n list.push(box)\n })\n }\n return states\n}\n","// HTML labels over the canvas: one absolutely positioned element per label, moved each frame to its\n// projected position. Crisp at any pixel ratio, styleable with CSS, and selectable/accessible like\n// any text on the page. Overlapping labels give way by priority (see labelLayout.js).\nimport { alignColumns, layoutLabels, leaderEnd, placeBox, stackColumns } from './labelLayout.js'\n\n/** @import { FrameLabel } from './frame.js' */\n\n/**\n * What happened to this frame's labels.\n * @typedef {object} LabelStats\n * @property {number} total\n * @property {number} shown\n * @property {number} overlapped hidden because a higher-priority label was in the way\n * @property {number} dimmed drawn faint because a higher-priority label or geometry was in front (overlap: 'dim')\n * @property {number} occluded hidden because geometry was in front (overlap: 'hide')\n * @property {number} offscreen behind the camera or outside the view\n * @property {number} zoomedOut hidden because the view isn't zoomed in to their minScale\n */\n\n/** @typedef {{ el: HTMLDivElement, text: string, className: string, width: number, height: number, showing: boolean, leader: SVGGElement | null, color: string, rule: number, label: FrameLabel | null, interactive: boolean }} Entry */\n\n/**\n * What the layer asks of its view: whether a label answers the pointer, and what to do when it does.\n * @typedef {object} LabelPointer\n * @property {(label: FrameLabel) => boolean} interactive\n * @property {(type: 'click' | 'over' | 'out', label: FrameLabel, event: MouseEvent | null) => void} on\n */\n\n/**\n * A leader line as drawn, in CSS pixels over the canvas - for image export.\n * @typedef {{ from: [number, number], to: [number, number], color: string, opacity: number }} Leader\n */\n\nconst SVG = 'http://www.w3.org/2000/svg'\n\n// how faint a covered label is drawn, with overlap: 'dim'\nconst DIM_OPACITY = '0.4'\n\nexport class LabelLayer {\n /** @type {HTMLDivElement | null} */ #root = null\n /** @type {Map<any, Entry>} */ #elements = new Map()\n /** Elements shown in the last frame, for image export. @type {HTMLDivElement[]} */\n shown = []\n /** Leader lines drawn in the last frame, for image export. @type {Leader[]} */\n leaders = []\n /** The lines from labels' points to callouts, under the labels. @type {SVGSVGElement | null} */ #lines = null\n /** Node overlays mounted in the layer. @type {Set<HTMLElement>} */ #overlays = new Set()\n /** @type {WeakMap<Element, Entry>} */ #byElement = new WeakMap()\n /** The label under the pointer, when it answers the pointer. @type {Entry | null} */ #over = null\n\n /** @param {HTMLCanvasElement} canvas @param {LabelPointer} [pointer] */\n constructor(canvas, pointer) {\n this.canvas = canvas\n this.pointer = pointer\n }\n\n /** The layer over the canvas: labels, and overlays such as legends. Made on first use. @returns {HTMLDivElement} */\n get root() {\n return this.#ensureRoot()\n }\n\n /**\n * Position, create, hide and remove label elements for this frame's labels, and mount the\n * overlays of the nodes drawn.\n * @param {(FrameLabel & { occluded?: boolean })[]} labels\n * @param {HTMLElement[]} [overlays]\n * @returns {LabelStats}\n */\n update(labels, overlays = []) {\n /** @type {LabelStats} */\n const stats = { total: labels.length, shown: 0, overlapped: 0, dimmed: 0, occluded: 0, offscreen: 0, zoomedOut: 0 }\n this.shown = []\n this.leaders = []\n if (!labels.length && !this.#elements.size && !overlays.length && !this.#overlays.size && !this.#root) return stats\n const root = this.#ensureRoot()\n this.#mount(root, overlays)\n const rect = this.canvas.getBoundingClientRect()\n this.#place(root)\n\n // 1. elements and text (writes only)\n const seen = new Set()\n /** @type {{ label: FrameLabel & { occluded?: boolean }, entry: Entry }[]} */\n const active = []\n for (const label of labels) {\n seen.add(label.key)\n if (!label.visible) stats.offscreen++\n // details for closer up: until then they take no part, so they can't push other labels out\n else if (label.style.minScale && label.scale * rect.height / 2 < label.style.minScale) stats.zoomedOut++\n else if (label.occluded && label.style.overlap === 'hide') stats.occluded++\n else active.push({ label, entry: this.#entry(label, root) })\n }\n for (const [key, entry] of this.#elements) {\n if (seen.has(key)) continue\n this.#leave(entry)\n entry.el.remove()\n entry.leader?.remove()\n this.#elements.delete(key)\n }\n // 2. measure new or changed labels (one layout pass for all of them)\n for (const { entry } of active) if (entry.width < 0) entry.el.style.display = ''\n for (const { entry } of active) {\n if (entry.width >= 0) continue\n // its own width, not the column's it was given\n entry.el.style.minWidth = ''\n entry.width = entry.el.offsetWidth\n entry.height = entry.el.offsetHeight\n }\n // 3. place, resolve overlaps, and write positions\n const boxes = active.map(({ label, entry }) => {\n const x = (label.ndc[0] * 0.5 + 0.5) * rect.width\n const y = (0.5 - label.ndc[1] * 0.5) * rect.height\n const [left, top] = placeBox(x, y, entry.width, entry.height, label.style.place, label.style.offset, label.style.edge, rect.width)\n // a label showing last frame holds its place more firmly, so labels don't flicker as the view moves\n return { left, top, width: entry.width, height: entry.height, priority: label.style.priority, overlap: label.style.overlap,\n depth: label.depth, sticky: entry.showing, covered: !!label.occluded, x, y, edge: label.style.edge }\n })\n // callouts in a column at an edge are lined up, and spaced out in order, never on top of each other\n alignColumns(boxes)\n stackColumns(boxes, rect.height)\n const states = layoutLabels(boxes)\n // remember what shows this frame, for next frame's stickiness\n for (const entry of this.#elements.values()) entry.showing = false\n const hidden = new Set(this.#elements.values())\n active.forEach(({ label, entry }, i) => {\n const state = states[i]\n entry.showing = state === 'show'\n if (state === 'hide') {\n stats.overlapped++\n return\n }\n hidden.delete(entry)\n // a label of something with click or hover handlers is part of it: it takes the pointer\n entry.label = label\n const interactive = !!this.pointer?.interactive(label)\n if (interactive !== entry.interactive) {\n entry.interactive = interactive\n entry.el.style.pointerEvents = interactive ? 'auto' : ''\n if (interactive) entry.el.dataset.interactive = ''\n else {\n delete entry.el.dataset.interactive\n this.#leave(entry)\n }\n }\n if (state === 'dim') stats.dimmed++\n else stats.shown++\n this.shown.push(entry.el)\n const el = entry.el, box = boxes[i]\n el.style.display = ''\n el.style.opacity = state === 'dim' ? DIM_OPACITY : ''\n // whole pixels keep text crisp - and the box is rounded too, so a leader meets the label where it is drawn\n box.left = Math.round(box.left)\n box.top = Math.round(box.top)\n el.style.transform = `translate(${box.left}px, ${box.top}px)`\n // a column's labels share its width; the right column's text keeps to the edge\n const edge = label.style.edge\n const minWidth = edge && entry.width !== box.width ? `${box.width}px` : '', textAlign = edge === 'right' ? 'right' : ''\n if (el.style.minWidth !== minWidth || el.style.textAlign !== textAlign) Object.assign(el.style, { minWidth, textAlign, boxSizing: minWidth ? 'border-box' : '' })\n // nearer labels stack above further ones, and every dimmed label sits under every shown one\n const near = Math.max(0, Math.round(100000 - label.depth * 100))\n el.style.zIndex = String(state === 'dim' ? Math.min(near, 99999) : 100000 + near)\n if (label.style.leader) this.#leader(entry, box, state === 'dim' ? +DIM_OPACITY : 1)\n else if (entry.leader) {\n entry.leader.remove()\n entry.leader = null\n }\n })\n for (const entry of hidden) {\n this.#leave(entry)\n entry.el.style.display = 'none'\n if (entry.leader) entry.leader.style.display = 'none'\n }\n return stats\n }\n\n /** @param {HTMLDivElement} root @param {HTMLElement[]} overlays */\n #mount(root, overlays) {\n const now = new Set(overlays)\n for (const el of now) {\n if (el.parentElement !== root) root.append(el)\n this.#overlays.add(el)\n }\n // overlays whose node is no longer drawn come off the page\n for (const el of this.#overlays) {\n if (now.has(el)) continue\n el.remove()\n this.#overlays.delete(el)\n }\n }\n\n /**\n * Draw a label's leader: from its point to the nearest point of its box, with a dot on the point.\n * @param {Entry} entry\n * @param {{ left: number, top: number, width: number, height: number, x: number, y: number, edge?: 'left' | 'right' | null }} box\n * @param {number} opacity\n */\n #leader(entry, box, opacity) {\n const { x, y } = box\n // the label's own text colour and underline (read once per look), unless CSS on .phoria-leader says otherwise\n if (!entry.color) {\n const cs = getComputedStyle(entry.el)\n entry.color = cs.color\n entry.rule = cs.borderBottomStyle === 'none' ? 0 : parseFloat(cs.borderBottomWidth) || 0\n }\n const end = leaderEnd(x, y, box, box.edge, entry.rule)\n let g = entry.leader\n if (!g) {\n g = /** @type {SVGGElement} */ (document.createElementNS(SVG, 'g'))\n g.append(document.createElementNS(SVG, 'line'), document.createElementNS(SVG, 'circle'))\n this.#ensureLines().append(g)\n entry.leader = g\n }\n const color = entry.color\n g.setAttribute('class', `phoria-leader${entry.className.slice('phoria-label'.length)}`)\n g.setAttribute('stroke', color)\n g.setAttribute('fill', color)\n g.style.display = ''\n g.style.opacity = String(opacity)\n const [line, dot] = /** @type {[SVGLineElement, SVGCircleElement]} */ (/** @type {unknown} */ ([...g.children]))\n // a point inside its own label needs no line\n line.style.display = end ? '' : 'none'\n if (end) {\n line.setAttribute('x1', String(x))\n line.setAttribute('y1', String(y))\n line.setAttribute('x2', String(end[0]))\n line.setAttribute('y2', String(end[1]))\n line.setAttribute('stroke-width', '1')\n }\n dot.setAttribute('cx', String(x))\n dot.setAttribute('cy', String(y))\n dot.setAttribute('r', '2.5')\n dot.setAttribute('stroke', 'none')\n if (end) this.leaders.push({ from: [x, y], to: end, color, opacity })\n }\n\n /** The SVG the leader lines go in, under every label. @returns {SVGSVGElement} */\n #ensureLines() {\n if (this.#lines) return this.#lines\n const svg = /** @type {SVGSVGElement} */ (document.createElementNS(SVG, 'svg'))\n svg.setAttribute('class', 'phoria-leaders')\n Object.assign(svg.style, { position: 'absolute', left: '0', top: '0', width: '100%', height: '100%', overflow: 'visible', zIndex: '0' })\n this.#ensureRoot().prepend(svg)\n this.#lines = svg\n return svg\n }\n\n /** The pointer is no longer on this label - it went, or stopped answering. @param {Entry} entry */\n #leave(entry) {\n if (this.#over !== entry) return\n this.#over = null\n if (entry.label) this.pointer?.on('out', entry.label, null)\n }\n\n dispose() {\n this.#over = null\n for (const el of this.#overlays) el.remove()\n this.#overlays.clear()\n this.#root?.remove()\n this.#root = null\n this.#lines = null\n this.#elements.clear()\n this.shown = []\n this.leaders = []\n }\n\n /** @param {FrameLabel} label @param {HTMLDivElement} root @returns {Entry} */\n #entry(label, root) {\n let entry = this.#elements.get(label.key)\n if (!entry) {\n const el = document.createElement('div')\n // opacity eases, so dimming and brightening don't flash\n Object.assign(el.style, { position: 'absolute', left: '0', top: '0', willChange: 'transform', transition: 'opacity 0.15s' })\n root.append(el)\n entry = { el, text: '', className: '', width: -1, height: -1, showing: false, leader: null, color: '', rule: 0, label: null, interactive: false }\n this.#elements.set(label.key, entry)\n this.#byElement.set(el, entry)\n }\n const className = `phoria-label${label.style.className ? ` ${label.style.className}` : ''}`\n if (entry.text !== label.text || entry.className !== className) {\n entry.el.textContent = entry.text = label.text\n entry.el.className = entry.className = className\n entry.width = entry.height = -1\n entry.color = ''\n }\n return entry\n }\n\n #ensureRoot() {\n if (this.#root) return this.#root\n // labels keep to one line unless the page's CSS says otherwise: a rule that any other wins over,\n // where an inline style would win over every rule\n if (!document.getElementById('phoria-labels-style')) {\n const style = document.createElement('style')\n style.id = 'phoria-labels-style'\n style.textContent = ':where(.phoria-label) { white-space: nowrap } :where(.phoria-label[data-interactive]) { cursor: pointer }'\n document.head.prepend(style)\n }\n const root = document.createElement('div')\n root.className = 'phoria-labels'\n // its own stacking context, so labels' depth ordering stays below the page's floating UI\n Object.assign(root.style, { position: 'absolute', pointerEvents: 'none', overflow: 'hidden', zIndex: '0', isolation: 'isolate' })\n // beside the canvas, in the same container: when that scrolls or moves, the labels go with it,\n // even while the view is idle and not redrawing\n this.canvas.after(root)\n this.#root = root\n this.#listen(root)\n this.#place(root)\n return root\n }\n\n /** Pass clicks and hovers on labels that answer the pointer to the view. @param {HTMLDivElement} root */\n #listen(root) {\n /** @param {Event} e */\n const entryOf = (e) => {\n const entry = this.#byElement.get(/** @type {Element} */ (e.target))\n return entry?.interactive && entry.label ? entry : null\n }\n root.addEventListener('click', (e) => {\n const entry = entryOf(e)\n if (entry?.label) this.pointer?.on('click', entry.label, e)\n })\n root.addEventListener('pointerover', (e) => {\n const entry = entryOf(e)\n if (!entry?.label || entry === this.#over) return\n this.#over = entry\n this.pointer?.on('over', entry.label, e)\n })\n root.addEventListener('pointerout', (e) => {\n const entry = entryOf(e)\n if (entry && entry === this.#over) this.#leave(entry)\n })\n }\n\n // cover the canvas: same offset parent, so the same offsets; fixed if the canvas is\n /** @param {HTMLDivElement} root */\n #place(root) {\n const c = this.canvas\n root.style.position = getComputedStyle(c).position === 'fixed' ? 'fixed' : 'absolute'\n root.style.left = `${c.offsetLeft + c.clientLeft}px`\n root.style.top = `${c.offsetTop + c.clientTop}px`\n root.style.width = `${c.clientWidth}px`\n root.style.height = `${c.clientHeight}px`\n }\n}\n","import { Vec3 } from './value/Vec3.js'\nimport { checkOneOf, checkOptions, checkRange, describe, fail } from './validate.js'\n\n/** @import { Camera } from './scene/cameras.js' */\n\n/** How far (CSS pixels) a press moves before it is a drag rather than a click - the View's rule too. */\nexport const DRAG_START = 4\n\n/**\n * @typedef {object} OrbitOptions\n * @property {boolean} [enabled] (default true)\n * @property {'orbit' | 'map'} [mode] 'map' makes every drag pan and the view never turn - for plans and maps (default 'orbit')\n * @property {number} [rotateSpeed] radians per pixel of drag (default 0.005)\n * @property {number} [zoomSpeed] fraction of the distance per wheel step (default 0.1)\n * @property {boolean} [zoom] false to leave the wheel scrolling the page (default true)\n * @property {boolean} [zoomToCursor] the wheel zooms towards the point under the pointer (default true)\n * @property {boolean} [pan] right-drag (or two-finger drag) pans (default true)\n * @property {number} [inertia] how much of a fling carries on after release: the fraction of its speed kept\n * every 1/60 s - 0 stops dead, 0.95 glides a long way (default 0.85)\n * @property {boolean | number} [autoRotate] spin around the target; a number is radians per second (default false)\n * @property {number} [minDistance] how close zooming gets to the target; for an orthographic camera, the\n * smallest height of the view (default 0.1)\n * @property {number} [maxDistance] how far zooming goes; for an orthographic camera, the largest height\n * of the view (default Infinity)\n * @property {number} [minPitch] radians below the horizon (default just short of straight down)\n * @property {number} [maxPitch] radians above it (default just short of straight up)\n */\n\nconst OPTIONS = ['enabled', 'mode', 'rotateSpeed', 'zoomSpeed', 'zoom', 'zoomToCursor', 'pan', 'inertia', 'autoRotate',\n 'minDistance', 'maxDistance', 'minPitch', 'maxPitch']\nconst HINTS = {\n enableDamping: \"use 'inertia' (0 to turn it off)\",\n enableRotate: \"use mode: 'map' to make dragging pan instead of turning\",\n rotate: \"use mode: 'map' to make dragging pan instead of turning\",\n enableZoom: \"use 'zoom'\",\n enablePan: \"use 'pan'\",\n screenSpacePanning: 'panning always follows the screen',\n dampingFactor: \"use 'inertia': the fraction of speed kept each 1/60 s (default 0.85)\",\n target: 'set camera.target - the control orbits around it',\n}\nconst LIMIT = Math.PI / 2 - 0.001\n// fastest fling, radians per second\nconst MAX_FLING = 4\n\n/** Check the numbers and modes in orbit options. @param {Record<string, any>} o */\nfunction checkSettings(o) {\n const owner = 'OrbitControl'\n if (o.mode !== undefined) checkOneOf(owner, 'mode', o.mode, ['orbit', 'map'])\n if (o.rotateSpeed !== undefined) checkRange(owner, 'rotateSpeed', o.rotateSpeed, 0)\n if (o.zoomSpeed !== undefined) checkRange(owner, 'zoomSpeed', o.zoomSpeed, 0)\n // the share of speed kept each 1/60 s: 1 would never slow down\n if (o.inertia !== undefined) checkRange(owner, 'inertia', o.inertia, 0, 0.99)\n if (o.autoRotate !== undefined && typeof o.autoRotate !== 'boolean' && (typeof o.autoRotate !== 'number' || !Number.isFinite(o.autoRotate))) {\n fail(owner, `'autoRotate' is true, false or a speed in radians per second, got ${describe(o.autoRotate)}`)\n }\n if (o.minDistance !== undefined) checkRange(owner, 'minDistance', o.minDistance, 0)\n if (o.maxDistance !== undefined) checkRange(owner, 'maxDistance', o.maxDistance, 0, Infinity, { above: true })\n if (o.minPitch !== undefined) checkRange(owner, 'minPitch', o.minPitch, -Math.PI / 2, Math.PI / 2)\n if (o.maxPitch !== undefined) checkRange(owner, 'maxPitch', o.maxPitch, -Math.PI / 2, Math.PI / 2)\n}\n\n/**\n * Mouse and touch camera control: drag (or one finger) orbits the camera around its target,\n * right-drag (or two fingers) pans, the wheel (or a pinch) zooms, towards the pointer. With\n * `mode: 'map'` it is a map control - every drag pans. A drag never counts as a click, so picking\n * on click keeps working. The View creates one with `orbit: true` and calls update()\n * each frame; standalone, call update(dt) yourself for inertia and auto-rotate.\n */\nexport class OrbitControl {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n enabled = true\n /** 'map' makes every drag pan. @type {'orbit' | 'map'} */\n mode = 'orbit'\n rotateSpeed = 0.005\n zoomSpeed = 0.1\n zoom = true\n zoomToCursor = true\n pan = true\n inertia = 0.85\n /** @type {boolean | number} */\n autoRotate = false\n minDistance = 0.1\n maxDistance = Infinity\n minPitch = -LIMIT\n maxPitch = LIMIT\n\n /** @type {Camera} */ camera\n /** @type {HTMLElement} */ element\n /** @type {Map<number, { x: number, y: number }>} */ #pointers = new Map()\n // fling speed in radians per second, measured while dragging\n #velocity = { yaw: 0, pitch: 0 }\n #lastMove = 0\n #panning = false\n #dragged = false\n /** where the press began, to tell a drag from a tap that wobbles @type {{ x: number, y: number }} */\n #pressed = { x: 0, y: 0 }\n #pinchDistance = 0\n /** @type {() => void} */ #removeListeners\n /** @type {(() => void) | null} */ #removePointer = null\n\n /**\n * @param {Camera} camera its target is the pivot; set to the origin if it has none\n * @param {HTMLElement} element usually the canvas\n * @param {OrbitOptions} [options]\n */\n constructor(camera, element, options = {}) {\n checkOptions('OrbitControl', options, OPTIONS, HINTS)\n if (!camera || !('target' in camera)) fail('OrbitControl', 'expects a camera, e.g. new OrbitControl(view.camera, view.canvas)')\n this.camera = camera\n this.element = element\n checkSettings(options)\n Object.assign(this, options)\n // the limits must still make sense with the defaults they're paired with\n if (this.minDistance > this.maxDistance) fail('OrbitControl', `'minDistance' (${this.minDistance}) is more than 'maxDistance' (${this.maxDistance})`)\n if (this.minPitch > this.maxPitch) fail('OrbitControl', `'minPitch' (${this.minPitch}) is more than 'maxPitch' (${this.maxPitch})`)\n camera.target ??= new Vec3()\n\n // touch-action: none stops the browser claiming touch drags for scrolling before we see them\n element.style.touchAction = 'none'\n const down = (e) => this.#down(e), move = (e) => this.#move(e), up = (e) => this.#up(e)\n const wheel = (e) => this.#wheel(e)\n const menu = (e) => { if (this.enabled && this.pan) e.preventDefault() }\n // capture phase, so a drag that ends over the element doesn't also count as a click\n const click = (e) => {\n if (this.#dragged) {\n e.stopImmediatePropagation()\n this.#dragged = false\n }\n }\n element.addEventListener('pointerdown', down)\n element.addEventListener('pointermove', move)\n element.addEventListener('pointerup', up)\n element.addEventListener('pointercancel', up)\n element.addEventListener('wheel', wheel, { passive: false })\n element.addEventListener('contextmenu', menu)\n element.addEventListener('click', click, true)\n this.#pointerHandlers = { down, move, up }\n this.#removePointer = () => {\n element.removeEventListener('pointerdown', down)\n element.removeEventListener('pointermove', move)\n element.removeEventListener('pointerup', up)\n element.removeEventListener('pointercancel', up)\n element.removeEventListener('click', click, true)\n }\n this.#removeListeners = () => {\n this.#removePointer?.()\n element.removeEventListener('wheel', wheel)\n element.removeEventListener('contextmenu', menu)\n }\n }\n\n /** @type {{ down: (e: PointerEvent) => void, move: (e: PointerEvent) => void, up: (e: PointerEvent) => void }} */\n #pointerHandlers\n\n /**\n * @internal Give the pointer to a View, which routes each press - to this orbit, or to dragging a\n * node - and decides what counts as a click. The wheel stays here. Returns what to call for each.\n * @returns {{ down: (e: PointerEvent) => void, move: (e: PointerEvent) => void, up: (e: PointerEvent) => void }}\n */\n handOverPointer() {\n this.#removePointer?.()\n this.#removePointer = null\n return this.#pointerHandlers\n }\n\n /** The target (pivot). @returns {Vec3} */\n get target() {\n return /** @type {Vec3} */ (this.camera.target)\n }\n\n /**\n * Camera position relative to the target: yaw 0 looks from +Z (the front), π/2 from +X (the right);\n * pitch is above the horizon. Setting it moves the camera, within the limits.\n * @returns {{ yaw: number, pitch: number, distance: number }}\n */\n get spherical() {\n const offset = this.camera.position.clone().sub(this.target)\n const distance = offset.len() || this.minDistance\n return { yaw: Math.atan2(offset[0], offset[2]), pitch: Math.asin(Math.max(-1, Math.min(1, offset[1] / distance))), distance }\n }\n\n set spherical({ yaw, pitch, distance }) {\n pitch = Math.min(this.maxPitch, Math.max(this.minPitch, pitch))\n // an orthographic camera's distance doesn't change the picture, so the limits are on its height\n if (!this.#orthographic) distance = Math.min(this.maxDistance, Math.max(this.minDistance, distance))\n const t = this.target\n this.camera.position.set(\n t[0] + distance * Math.cos(pitch) * Math.sin(yaw),\n t[1] + distance * Math.sin(pitch),\n t[2] + distance * Math.cos(pitch) * Math.cos(yaw))\n }\n\n /** Orbit by angles in radians. @param {number} dYaw @param {number} dPitch */\n rotate(dYaw, dPitch) {\n const s = this.spherical\n this.spherical = { yaw: s.yaw + dYaw, pitch: s.pitch + dPitch, distance: s.distance }\n }\n\n /** Scale the distance to the target (0.9 moves closer). Orthographic cameras zoom their view height. @param {number} factor */\n zoomBy(factor) {\n const cam = /** @type {any} */ (this.camera)\n if (this.#orthographic) {\n cam.height = Math.min(this.maxDistance, Math.max(this.minDistance, 1e-4, cam.height * factor))\n return\n }\n const s = this.spherical\n this.spherical = { ...s, distance: s.distance * factor }\n }\n\n /**\n * Zoom by a factor, keeping the point under the pointer still - where the pointer is, in -1..1\n * across the view (x right, y up). The target moves with it, so orbiting then turns about there.\n * @param {number} factor below 1 zooms in\n * @param {number} x @param {number} y\n */\n zoomAt(factor, x, y) {\n const before = this.#halfHeight()\n this.zoomBy(factor)\n // the zoom actually applied, after the distance limits\n const k = 1 - this.#halfHeight() / before\n if (!k) return\n this.camera.updateWorld()\n const m = this.camera.worldMatrix\n const right = new Vec3(m[0], m[1], m[2]).normalize().multiplyScalar(x * before * this.camera.aspect * k)\n const move = new Vec3(m[4], m[5], m[6]).normalize().multiplyScalar(y * before * k).add(right)\n this.camera.position.add(move)\n this.target.add(move)\n }\n\n get #orthographic() {\n return /** @type {any} */ (this.camera).constructor.type === 'orthographic-camera'\n }\n\n // half the view's height at the target, in world units\n #halfHeight() {\n const cam = /** @type {any} */ (this.camera)\n return this.#orthographic ? cam.height / 2 : this.spherical.distance * Math.tan(cam.fov * Math.PI / 360)\n }\n\n /** Move the camera and target together by screen pixels; the scene follows the pointer. @param {number} dx @param {number} dy */\n panBy(dx, dy) {\n this.camera.updateWorld()\n const m = this.camera.worldMatrix\n const right = new Vec3(m[0], m[1], m[2]).normalize()\n const up = new Vec3(m[4], m[5], m[6]).normalize()\n const cam = /** @type {any} */ (this.camera)\n const height = this.element.clientHeight || 1\n const worldPerPixel = this.#orthographic\n ? cam.height / height\n : 2 * this.spherical.distance * Math.tan((cam.fov * Math.PI / 180) / 2) / height\n const move = right.multiplyScalar(-dx * worldPerPixel).add(up.multiplyScalar(dy * worldPerPixel))\n this.camera.position.add(move)\n this.target.add(move)\n }\n\n /**\n * Apply inertia and auto-rotate; the View calls this each frame.\n * @param {number} dt seconds\n * @param {boolean} [still] hold auto-rotation - the View passes its reducedMotion\n */\n update(dt, still = false) {\n if (!this.enabled) return\n if (this.#pointers.size === 0) {\n const v = this.#velocity\n if (Math.abs(v.yaw) > 1e-3 || Math.abs(v.pitch) > 1e-3) {\n this.rotate(v.yaw * dt, v.pitch * dt)\n // the same glide at any frame rate\n const keep = Math.pow(Math.min(0.99, Math.max(0, this.inertia)), dt * 60)\n v.yaw *= keep\n v.pitch *= keep\n }\n if (this.autoRotate && !still) this.rotate(-(this.autoRotate === true ? 0.5 : this.autoRotate) * dt, 0)\n }\n }\n\n /**\n * Let go of the gesture under way - for an app taking the pointer over, such as to drag\n * something across the scene. The camera stays where it is; the next press orbits as usual.\n */\n cancel() {\n this.#pointers.clear()\n this.#pinchDistance = 0\n this.#velocity = { yaw: 0, pitch: 0 }\n this.#dragged = false\n }\n\n dispose() {\n this.#removeListeners()\n this.element.style.touchAction = ''\n }\n\n /** @param {PointerEvent} e */\n #down(e) {\n if (!this.enabled || (e.pointerType === 'mouse' && e.button !== 0 && e.button !== 2)) return\n if (e.button === 2 && !this.pan) return\n // capture is best-effort: it throws for pointers the browser doesn't know, such as scripted events\n try { this.element.setPointerCapture(e.pointerId) } catch { /* drags still work inside the element */ }\n this.#pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })\n this.#pressed = { x: e.clientX, y: e.clientY }\n this.#dragged = false\n this.#velocity = { yaw: 0, pitch: 0 }\n this.#lastMove = performance.now()\n this.#pinchDistance = this.#spread()\n // as a map control, every drag pans\n this.#panning = e.button === 2 || this.mode === 'map'\n if (this.#panning && !this.pan) this.#pointers.delete(e.pointerId)\n }\n\n /** @param {PointerEvent} e */\n #move(e) {\n const last = this.#pointers.get(e.pointerId)\n if (!last || !this.enabled) return\n const dx = e.clientX - last.x, dy = e.clientY - last.y\n last.x = e.clientX\n last.y = e.clientY\n // a tap that moves a pixel or two is still a click - touch and pens nearly always do\n if (!this.#dragged && Math.hypot(e.clientX - this.#pressed.x, e.clientY - this.#pressed.y) >= DRAG_START) this.#dragged = true\n\n if (this.#pointers.size >= 2) {\n // two fingers: pinch zooms, moving together pans (applied per finger, so halve it)\n const spread = this.#spread()\n if (this.zoom && this.#pinchDistance > 0 && spread > 0) this.zoomBy(this.#pinchDistance / spread)\n this.#pinchDistance = spread\n if (this.pan) this.panBy(dx / 2, dy / 2)\n } else if (this.#panning) {\n this.panBy(dx, dy)\n } else {\n // grab the scene: dragging right turns it right, dragging down tips its top towards you\n const dYaw = -dx * this.rotateSpeed, dPitch = dy * this.rotateSpeed\n this.rotate(dYaw, dPitch)\n // speed from the time since the last move, capped so one big jump can't fling it round\n const now = performance.now()\n const elapsed = Math.max(1 / 60, (now - this.#lastMove) / 1000)\n const cap = (w) => Math.max(-MAX_FLING, Math.min(MAX_FLING, w / elapsed))\n this.#velocity = { yaw: cap(dYaw), pitch: cap(dPitch) }\n this.#lastMove = now\n }\n }\n\n /** @param {PointerEvent} e */\n #up(e) {\n this.#pointers.delete(e.pointerId)\n this.#pinchDistance = this.#spread()\n // no fling if the pointer had come to rest before letting go\n if (this.inertia <= 0 || performance.now() - this.#lastMove > 80) this.#velocity = { yaw: 0, pitch: 0 }\n }\n\n /** @param {WheelEvent} e */\n #wheel(e) {\n if (!this.enabled || !this.zoom) return\n e.preventDefault()\n const factor = 1 + Math.sign(e.deltaY) * this.zoomSpeed\n if (!this.zoomToCursor) return this.zoomBy(factor)\n const r = this.element.getBoundingClientRect()\n this.zoomAt(factor, ((e.clientX - r.left) / r.width) * 2 - 1, 1 - ((e.clientY - r.top) / r.height) * 2)\n }\n\n #spread() {\n if (this.#pointers.size < 2) return 0\n const [a, b] = [...this.#pointers.values()]\n return Math.hypot(a.x - b.x, a.y - b.y)\n }\n}\n","import * as mat3 from '../math/mat3.js'\nimport * as mat4 from '../math/mat4.js'\nimport * as quat from '../math/quat.js'\nimport { Mat4 } from '../value/Mat4.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { checkNumber, fail } from '../validate.js'\nimport { NODE_OPTIONS, Node, inParentSpace, setPoint } from './Node.js'\n\n/** @import { NodeOptions } from './Node.js' */\n/** @import { Vec3Input } from '../types.js' */\n\nconst UP = new Float32Array([0, 1, 0])\nconst tmp = new Float32Array(16)\nconst tmp3 = new Float32Array(9)\n\n/**\n * Turn a node to face a target given in its parent's space (the same space as its position).\n * @param {Node} node @param {Vec3} target\n */\nexport function aimAt(node, target) {\n if (node.position.equals(target, 1e-9)) return\n const dir = target.clone().sub(node.position).normalize()\n // world up keeps the picture upright, and turns it smoothly with the view right up to straight up\n // or down - the orbit stops a thousandth of a radian short. Only within a hair of exactly vertical\n // (the 'top' preset's view), where up would no longer say which way the screen faces, is north up\n const up = Math.hypot(dir[0], dir[2]) < 5e-4 ? [0, 0, -1] : UP\n mat4.targetTo(tmp, node.position, target, up)\n const q = quat.normalize(new Float32Array(4), quat.fromMat3(new Float32Array(4), mat3.fromMat4(tmp3, tmp)))\n node.quaternion.copy(q)\n}\n\n/**\n * @typedef {NodeOptions & { near?: number, far?: number, target?: Vec3Input }} CameraOptions\n */\n\nconst CAMERA_OPTIONS = [...NODE_OPTIONS, 'near', 'far', 'target', 'aspect']\nconst CAMERA_HINTS = {\n lookAt: \"use target: [x, y, z], or call camera.lookAt(...) after creating it\",\n zoom: \"move the camera, or change 'fov' (perspective) or 'height' (orthographic)\",\n}\n\n/** Base for cameras. Cameras look down their local -Z axis. */\nexport class Camera extends Node {\n static OPTIONS = CAMERA_OPTIONS\n static HINTS = CAMERA_HINTS\n\n near = 0.1\n far = 1000\n /** Width / height - set by the View to match the canvas. */\n aspect = 1\n /** @type {Vec3 | null} */ #target = null\n\n /** @param {CameraOptions & { aspect?: number }} [options] */\n constructor(options = {}) {\n super(options)\n const owner = this.constructor.name\n if (options.near !== undefined) this.near = checkNumber(owner, 'near', options.near)\n if (options.far !== undefined) this.far = checkNumber(owner, 'far', options.far)\n if (options.aspect !== undefined) this.aspect = checkNumber(owner, 'aspect', options.aspect)\n if (!(this.near > 0) || !(this.far > this.near)) fail(owner, `needs 0 < near < far, got near ${this.near} and far ${this.far}`)\n if (options.target !== undefined) this.target = Vec3.fromInput(options.target, owner)\n }\n\n /**\n * When set, the camera turns to face it every frame. In the same space as `position` (world\n * space for a camera that isn't parented). Orbit controls use it as their pivot. Assigning copies\n * the point in: camera.target = [0, 1, 0]; null lets the camera turn freely.\n * @returns {Vec3 | null}\n */\n get target() { return this.#target }\n /** @param {import('../types.js').Vec3Input | null} v */\n set target(v) { this.#target = setPoint(this.#target, v, this.constructor.name) }\n\n updateMatrix() {\n if (this.target) aimAt(this, this.target)\n return super.updateMatrix()\n }\n\n /**\n * Look at a world position or node. A camera with a target keeps aiming at it - every View camera\n * has one, and its orbit control turns about it - so the target moves there instead.\n * @param {import('../types.js').Vec3Input | Node} target @param {import('../types.js').Vec3Input} [up]\n * @returns {this}\n */\n lookAt(target, up) {\n if (!this.target) return super.lookAt(target, up)\n this.target.copy(inParentSpace(this, target))\n return this\n }\n\n /** The projection matrix for the current settings. @returns {Mat4} */\n get projectionMatrix() {\n return new Mat4()\n }\n\n /** The inverse of the world matrix, as of the last update. @returns {Mat4} */\n get viewMatrix() {\n return this.worldMatrix.clone().invert()\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), near: this.near, far: this.far, aspect: this.aspect, ...(this.target ? { target: this.target.toArray() } : {}) }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = {}\n if (this.near !== 0.1) json.near = this.near\n if (this.far !== 1000) json.far = this.far\n if (this.target) json.target = this.target.toArray()\n return json\n }\n}\n\n/** A camera with perspective: things further away look smaller. */\nexport class PerspectiveCamera extends Camera {\n static type = 'perspective-camera'\n static get OPTIONS() { return [...CAMERA_OPTIONS, 'fov'] }\n\n /** Vertical field of view in degrees. */\n fov = 50\n\n /** @param {CameraOptions & { fov?: number }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.fov !== undefined) {\n this.fov = checkNumber('PerspectiveCamera', 'fov', options.fov)\n if (this.fov <= 0 || this.fov >= 180) fail('PerspectiveCamera', `'fov' is the vertical angle in degrees, 0-180 exclusive, got ${this.fov}`)\n }\n }\n\n get projectionMatrix() {\n return mat4.perspective(new Mat4(), this.fov * Math.PI / 180, this.aspect, this.near, this.far)\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), fov: this.fov }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.fov !== 50 ? { fov: this.fov } : {}) }\n }\n}\n\n/** A camera without perspective: sizes don't change with distance. Isometric views, 2D-ish data viz. */\nexport class OrthographicCamera extends Camera {\n static type = 'orthographic-camera'\n static get OPTIONS() { return [...CAMERA_OPTIONS, 'height'] }\n\n /** Height of the view in world units; the width follows the aspect. */\n height = 10\n\n /** @param {CameraOptions & { height?: number }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.height !== undefined) this.height = checkNumber('OrthographicCamera', 'height', options.height)\n }\n\n get projectionMatrix() {\n const h = this.height / 2, w = h * this.aspect\n return mat4.ortho(new Mat4(), -w, w, -h, h, this.near, this.far)\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), height: this.height }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.height !== 10 ? { height: this.height } : {}) }\n }\n}\n","// Named camera setups for the common business views: an isometric diorama, a plan from above, a\n// front or side elevation, or a plain perspective. The View fits a preset camera to the scene.\nimport { OrthographicCamera, PerspectiveCamera } from './scene/cameras.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { fail, didYouMean } from './validate.js'\n\n/** @import { Box3 } from './value/Box3.js' */\n\n/** @typedef {'perspective' | 'isometric' | 'top' | 'front' | 'side'} CameraPreset */\n\n/** Direction from the target to the camera, per preset. */\nconst DIRECTIONS = {\n perspective: [0.6, 0.45, 1],\n isometric: [1, 1, 1],\n top: [0, 1, 0],\n front: [0, 0, 1],\n side: [1, 0, 0],\n}\nexport const CAMERA_PRESETS = /** @type {CameraPreset[]} */ (Object.keys(DIRECTIONS))\n\n// words people use for these views\nconst ALIASES = {\n ortho: 'isometric', orthographic: 'isometric', iso: 'isometric', plan: 'top', overhead: 'top', above: 'top',\n map: 'top', elevation: 'front', left: 'side', right: 'side', persp: 'perspective', '3d': 'perspective',\n}\n\n/**\n * A camera for a preset, looking at `target` from `distance` away. Every preset but 'perspective'\n * is orthographic, so sizes don't shrink with distance - the norm for diagrams and plans.\n * @param {CameraPreset} name\n * @param {{ target?: ArrayLike<number>, distance?: number }} [from]\n * @returns {PerspectiveCamera | OrthographicCamera}\n */\nexport function cameraPreset(name, { target = [0, 0, 0], distance = 10 } = {}) {\n const direction = presetDirection(name)\n const position = new Vec3(target[0], target[1], target[2]).add(direction.multiplyScalar(distance))\n return name === 'perspective'\n ? new PerspectiveCamera({ fov: 45, position, target: [target[0], target[1], target[2]] })\n : new OrthographicCamera({ height: distance, position, target: [target[0], target[1], target[2]], far: Math.max(1000, distance * 20) })\n}\n\n/**\n * The unit direction from the target to a preset's camera.\n * @param {CameraPreset} name\n * @returns {Vec3}\n */\nexport function presetDirection(name) {\n if (!(name in DIRECTIONS)) {\n const alias = ALIASES[String(name).toLowerCase()]\n fail('View', `camera '${name}' is not a preset - ${alias ? `use '${alias}'` : `expected one of ${CAMERA_PRESETS.map((p) => `'${p}'`).join(', ')}${didYouMean(String(name), CAMERA_PRESETS)}`}`)\n }\n return new Vec3(...DIRECTIONS[name]).normalize()\n}\n\n// where a perspective picture's middle sits, below the view's middle (in half-heights of the view):\n// a little low, so things standing on a floor look grounded rather than hung from the top edge\nconst LOW = 0.12\n\n/**\n * How to fit a set of points in view from `direction`: where to look (the centre) and the distance\n * for a perspective camera (give `fov`), or the view height for an orthographic one. Every point\n * lands inside the view with `padding` to spare. Fitting the corners of each thing drawn, rather\n * than one box round them all, keeps a picture from sitting small in the box's empty corners. An\n * orthographic picture is centred; a perspective one - whose near side looks bigger - is moved\n * until it sits just below the middle, filling as much of the view as that allows.\n * @param {ArrayLike<number>[]} points world positions, at least one\n * @param {ArrayLike<number>} direction a unit vector from the points towards the camera\n * @param {{ aspect: number, fov?: number, padding?: number }} view fov in degrees, vertical (perspective; leave it out for\n * orthographic); padding is the margin as a fraction of the size, as for view.frame()\n * @returns {{ center: Vec3, size: number }}\n */\nexport function fitPoints(points, direction, { aspect, fov, padding = 0 }) {\n const scale = 1 + padding, wide = aspect > 0 ? aspect : 1\n const ahead = new Vec3(-direction[0], -direction[1], -direction[2])\n const right = ahead.clone().cross(Math.abs(ahead[1]) > 0.9999 ? [0, 0, -1] : [0, 1, 0]).normalize()\n const up = right.clone().cross(ahead)\n const axes = [right, up, ahead]\n // the points in the camera's axes, and the middle of their spread\n const local = points.map((p) => axes.map((a) => p[0] * a[0] + p[1] * a[1] + p[2] * a[2]))\n const lo = [0, 1, 2].map((k) => Math.min(...local.map((q) => q[k]))), hi = [0, 1, 2].map((k) => Math.max(...local.map((q) => q[k])))\n const mid = [0, 1, 2].map((k) => (lo[k] + hi[k]) / 2)\n const world = (k) => right[k] * mid[0] + up[k] * mid[1] + ahead[k] * mid[2]\n const centerOf = () => new Vec3(world(0), world(1), world(2))\n if (fov === undefined) {\n const half = Math.max((hi[1] - lo[1]) / 2, (hi[0] - lo[0]) / 2 / wide) * scale\n return { center: centerOf(), size: Math.max(half * 2, 1e-3) }\n }\n const tanV = Math.tan(fov * Math.PI / 360), tanH = tanV * wide\n const near = Math.max(...[0, 1, 2].map((k) => hi[k] - lo[k]), 1e-3) * 0.05\n // back far enough that every point, about the centre, is inside the view\n const distance = () => Math.max(1e-3, ...local.map((q) => {\n const x = Math.abs(q[0] - mid[0]) * scale, y = Math.abs(q[1] - mid[1]) * scale, z = q[2] - mid[2]\n return Math.max(x / tanH - z, y / tanV - z, near - z)\n }))\n let d = distance()\n for (let i = 0; i < 8; i++) {\n // where the points land, from -1 to 1 across the view: move the centre until their middle is\n // across the middle of the view, and just below it\n let u0 = Infinity, u1 = -Infinity, v0 = Infinity, v1 = -Infinity\n for (const q of local) {\n const depth = d + q[2] - mid[2], u = (q[0] - mid[0]) / depth / tanH, v = (q[1] - mid[1]) / depth / tanV\n u0 = Math.min(u0, u); u1 = Math.max(u1, u); v0 = Math.min(v0, v); v1 = Math.max(v1, v)\n }\n const du = (u0 + u1) / 2, dv = (v0 + v1) / 2 + LOW\n if (Math.abs(du) < 1e-4 && Math.abs(dv) < 1e-4) break\n mid[0] += du * tanH * d\n mid[1] += dv * tanV * d\n d = distance()\n }\n return { center: centerOf(), size: d }\n}\n\n/** @typedef {'height' | 'width' | 'both'} FramingKeep */\n\n/**\n * How much bigger (or smaller) the view must be to keep a camera's framing when the canvas's shape\n * changes from `designed` (the aspect the framing was set for) to `aspect`. 'height' keeps the\n * framed height (the width varies - the default for any camera); 'width' keeps the framed width;\n * 'both' keeps everything framed in view, widening for narrower canvases and keeping the height for\n * wider ones.\n * @param {FramingKeep} keep @param {number} designed @param {number} aspect\n * @returns {number} the factor for an orthographic camera's height, or a perspective camera's distance\n */\nexport function framingScale(keep, designed, aspect) {\n if (keep === 'height' || !(aspect > 0) || !(designed > 0)) return 1\n const ratio = designed / aspect\n return keep === 'width' ? ratio : Math.max(1, ratio)\n}\n","// Easing: how progress runs from 0 to 1 - steady, or easing in and out. One table for timelines\n// (phoria2/motion) and charts' transitions, so both take the same names.\n\n/** @typedef {'linear' | 'in' | 'out' | 'inOut'} EaseName */\n\n/** @type {Record<EaseName, (t: number) => number>} */\nexport const EASES = {\n linear: (t) => t,\n in: (t) => t * t * t,\n out: (t) => 1 - (1 - t) ** 3,\n inOut: (t) => (t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2),\n}\n","import { Vec3 } from './Vec3.js'\n\nconst edge1 = new Vec3(), edge2 = new Vec3(), pvec = new Vec3(), tvec = new Vec3(), qvec = new Vec3()\n\n/** A ray: an origin and a (normalised) direction. */\nexport class Ray {\n origin = new Vec3()\n direction = new Vec3(0, 0, -1)\n\n /** @param {ArrayLike<number>} [origin] @param {ArrayLike<number>} [direction] */\n constructor(origin, direction) {\n if (origin) this.origin.set(origin[0], origin[1], origin[2])\n if (direction) this.direction.set(direction[0], direction[1], direction[2]).normalize()\n }\n\n /** The point at distance t along the ray. @param {number} t @param {Vec3} [out] @returns {Vec3} */\n at(t, out = new Vec3()) {\n return out.copy(this.direction).multiplyScalar(t).add(this.origin)\n }\n\n /** @returns {Ray} */\n clone() {\n return new Ray(this.origin, this.direction)\n }\n\n /** Transform by a 4x4 (direction ignores translation, and is re-normalised). @param {ArrayLike<number>} m @returns {this} */\n applyMatrix4(m) {\n const end = this.at(1)\n this.origin.applyMatrix4(/** @type {Float32Array} */ (m))\n end.applyMatrix4(/** @type {Float32Array} */ (m))\n this.direction.copy(end).sub(this.origin).normalize()\n return this\n }\n\n /** Distance to where the ray enters a sphere, or null if it misses (or the sphere is behind). @param {ArrayLike<number>} center @param {number} radius @returns {number | null} */\n intersectSphere(center, radius) {\n tvec.set(center[0], center[1], center[2]).sub(this.origin)\n const along = tvec.dot(this.direction)\n const d2 = tvec.dot(tvec) - along * along\n const r2 = radius * radius\n if (d2 > r2) return null\n const half = Math.sqrt(r2 - d2)\n const t0 = along - half, t1 = along + half\n if (t1 < 0) return null\n return t0 < 0 ? t1 : t0\n }\n\n /**\n * Distance to where the ray meets a plane - given by its normal and a point on it - or null when\n * it runs along the plane or the plane is behind it. For dragging things across a floor:\n * ray.at(ray.intersectPlane([0, 1, 0], [0, 0, 0])).\n * @param {ArrayLike<number>} normal @param {ArrayLike<number>} point\n * @returns {number | null}\n */\n intersectPlane(normal, point) {\n const across = normal[0] * this.direction[0] + normal[1] * this.direction[1] + normal[2] * this.direction[2]\n if (Math.abs(across) < 1e-9) return null\n const t = (normal[0] * (point[0] - this.origin[0]) + normal[1] * (point[1] - this.origin[1]) + normal[2] * (point[2] - this.origin[2])) / across\n return t >= 0 ? t : null\n }\n\n /**\n * Möller-Trumbore ray/triangle test: the distance along the ray and barycentric (u, v), or null.\n * Triangles facing away (clockwise from the ray's side) are skipped when cullBack is set.\n * @param {ArrayLike<number>} a @param {ArrayLike<number>} b @param {ArrayLike<number>} c\n * @param {boolean} cullBack\n * @returns {{ t: number, u: number, v: number } | null}\n */\n intersectTriangle(a, b, c, cullBack) {\n edge1.set(b[0] - a[0], b[1] - a[1], b[2] - a[2])\n edge2.set(c[0] - a[0], c[1] - a[1], c[2] - a[2])\n pvec.copy(this.direction).cross(edge2)\n const det = edge1.dot(pvec)\n if (cullBack ? det < 1e-10 : Math.abs(det) < 1e-10) return null\n const inv = 1 / det\n tvec.set(this.origin[0] - a[0], this.origin[1] - a[1], this.origin[2] - a[2])\n const u = tvec.dot(pvec) * inv\n if (u < 0 || u > 1) return null\n qvec.copy(tvec).cross(edge1)\n const v = this.direction.dot(qvec) * inv\n if (v < 0 || u + v > 1) return null\n const t = edge2.dot(qvec) * inv\n return t >= 0 ? { t, u, v } : null\n }\n\n /** Squared distance from the ray to a point, and how far along the ray the closest approach is. @param {ArrayLike<number>} p @returns {{ distanceSq: number, t: number }} */\n distanceSqToPoint(p) {\n tvec.set(p[0] - this.origin[0], p[1] - this.origin[1], p[2] - this.origin[2])\n const t = Math.max(0, tvec.dot(this.direction))\n const closest = this.at(t, qvec)\n return { distanceSq: (p[0] - closest[0]) ** 2 + (p[1] - closest[1]) ** 2 + (p[2] - closest[2]) ** 2, t }\n }\n\n /**\n * Squared distance between the ray and a line segment, with the closest points' parameters.\n * @param {ArrayLike<number>} v0 @param {ArrayLike<number>} v1\n * @returns {{ distanceSq: number, t: number, s: number }} t along the ray, s 0-1 along the segment\n */\n distanceSqToSegment(v0, v1) {\n // closest points between two lines, then clamped to the ray (t >= 0) and segment (0 <= s <= 1)\n const d = this.direction\n const ex = v1[0] - v0[0], ey = v1[1] - v0[1], ez = v1[2] - v0[2]\n const wx = this.origin[0] - v0[0], wy = this.origin[1] - v0[1], wz = this.origin[2] - v0[2]\n const a = 1, b = d[0] * ex + d[1] * ey + d[2] * ez, c = ex * ex + ey * ey + ez * ez\n const dd = d[0] * wx + d[1] * wy + d[2] * wz, e = ex * wx + ey * wy + ez * wz\n const denom = a * c - b * b\n let s = denom > 1e-12 ? (a * e - b * dd) / denom : 0\n s = Math.min(1, Math.max(0, s))\n let t = b * s - dd\n // nearest behind the ray's start: from the start, the nearest point of the segment is another one\n if (t < 0) {\n t = 0\n s = c > 1e-12 ? Math.min(1, Math.max(0, e / c)) : 0\n }\n const px = this.origin[0] + d[0] * t - (v0[0] + ex * s)\n const py = this.origin[1] + d[1] * t - (v0[1] + ey * s)\n const pz = this.origin[2] + d[2] * t - (v0[2] + ez * s)\n return { distanceSq: px * px + py * py + pz * pz, t, s }\n }\n}\n","// A bounding volume hierarchy over a geometry's triangles, so a ray tests a few dozen boxes and a\n// handful of triangles rather than every triangle - picking, label occlusion and the exact step of\n// GPU picking stay quick on models of hundreds of thousands of triangles. Built the first time a\n// ray needs it, and again only when the geometry changes (needsUpdate()).\n\n/** @import { Geometry } from './Geometry.js' */\n\n// triangles in a leaf, at most\nconst LEAF = 8\n// below this, testing every triangle is as quick as building and walking a tree\nexport const BVH_MIN_TRIANGLES = 128\n\n/**\n * @typedef {object} BVH\n * @property {Float32Array} boxes min xyz, max xyz per node\n * @property {Int32Array} nodes per node: the first child (inner) or first triangle slot (leaf),\n * and the triangle count (0 for an inner node, whose children are at first and first + 1)\n * @property {Uint32Array} order triangle indices, grouped by leaf\n */\n\n/** @type {WeakMap<Geometry, { version: number, count: number, bvh: BVH }>} */\nconst cache = new WeakMap()\n\n/**\n * The geometry's BVH over its first `count` triangles, built now if it hasn't been or the geometry\n * has changed since.\n * @param {Geometry} g @param {number} count triangles\n * @returns {BVH}\n */\nexport function bvhOf(g, count) {\n const hit = cache.get(g)\n if (hit && hit.version === g.version && hit.count === count) return hit.bvh\n const bvh = build(g, count)\n cache.set(g, { version: g.version, count, bvh })\n return bvh\n}\n\n/** @param {Geometry} g @param {number} count @returns {BVH} */\nfunction build(g, count) {\n const p = g.positions, idx = g.indices\n const corner = (f, k) => (idx ? idx[f * 3 + k] : f * 3 + k) * 3\n // each triangle's box and centre\n const tri = new Float32Array(count * 9)\n for (let f = 0; f < count; f++) {\n const a = corner(f, 0), b = corner(f, 1), c = corner(f, 2)\n for (let k = 0; k < 3; k++) {\n const lo = Math.min(p[a + k], p[b + k], p[c + k]), hi = Math.max(p[a + k], p[b + k], p[c + k])\n tri[f * 9 + k] = lo\n tri[f * 9 + 3 + k] = hi\n tri[f * 9 + 6 + k] = (lo + hi) / 2\n }\n }\n const order = new Uint32Array(count)\n for (let f = 0; f < count; f++) order[f] = f\n const maxNodes = Math.max(1, 2 * Math.ceil(count / LEAF) * 2)\n let boxes = new Float32Array(maxNodes * 6), nodes = new Int32Array(maxNodes * 2), used = 0\n const grow = () => {\n const b = new Float32Array(boxes.length * 2), n = new Int32Array(nodes.length * 2)\n b.set(boxes); n.set(nodes)\n boxes = b; nodes = n\n }\n const alloc = () => {\n if ((used + 1) * 2 > nodes.length) grow()\n return used++\n }\n // split [start, end) of order into the node at `at`, longest axis of the centres, at the median\n const stack = [[alloc(), 0, count]]\n while (stack.length) {\n const [at, start, end] = /** @type {number[]} */ (stack.pop())\n let x0 = Infinity, y0 = Infinity, z0 = Infinity, x1 = -Infinity, y1 = -Infinity, z1 = -Infinity\n let cx0 = Infinity, cy0 = Infinity, cz0 = Infinity, cx1 = -Infinity, cy1 = -Infinity, cz1 = -Infinity\n for (let i = start; i < end; i++) {\n const t = order[i] * 9\n x0 = Math.min(x0, tri[t]); y0 = Math.min(y0, tri[t + 1]); z0 = Math.min(z0, tri[t + 2])\n x1 = Math.max(x1, tri[t + 3]); y1 = Math.max(y1, tri[t + 4]); z1 = Math.max(z1, tri[t + 5])\n cx0 = Math.min(cx0, tri[t + 6]); cy0 = Math.min(cy0, tri[t + 7]); cz0 = Math.min(cz0, tri[t + 8])\n cx1 = Math.max(cx1, tri[t + 6]); cy1 = Math.max(cy1, tri[t + 7]); cz1 = Math.max(cz1, tri[t + 8])\n }\n boxes.set([x0, y0, z0, x1, y1, z1], at * 6)\n const sx = cx1 - cx0, sy = cy1 - cy0, sz = cz1 - cz0\n if (end - start <= LEAF || Math.max(sx, sy, sz) <= 0) {\n nodes[at * 2] = start\n nodes[at * 2 + 1] = end - start\n continue\n }\n const axis = sx >= sy && sx >= sz ? 6 : sy >= sz ? 7 : 8\n const mid = (start + end) >> 1\n partition(order, tri, axis, start, end, mid)\n const left = alloc()\n alloc()\n nodes[at * 2] = left\n nodes[at * 2 + 1] = 0\n stack.push([left, start, mid], [left + 1, mid, end])\n }\n return { boxes: boxes.slice(0, used * 6), nodes: nodes.slice(0, used * 2), order }\n}\n\n/**\n * Put the k-th smallest (by centre on `axis`) at k, smaller before it and larger after - quickselect.\n * @param {Uint32Array} order @param {Float32Array} tri @param {number} axis @param {number} lo @param {number} hi @param {number} k\n */\nfunction partition(order, tri, axis, lo, hi, k) {\n let l = lo, r = hi - 1\n while (l < r) {\n const pivot = tri[order[(l + r) >> 1] * 9 + axis]\n let i = l, j = r\n while (i <= j) {\n while (tri[order[i] * 9 + axis] < pivot) i++\n while (tri[order[j] * 9 + axis] > pivot) j--\n if (i <= j) {\n const s = order[i]; order[i] = order[j]; order[j] = s\n i++; j--\n }\n }\n if (k <= j) r = j\n else if (k >= i) l = i\n else break\n }\n}\n\n/**\n * Walk the tree along a ray, nearest boxes first, calling `test(triangle)` for each triangle in a\n * leaf the ray reaches. `test` returns the distance of the nearest hit so far (Infinity for none),\n * and boxes further than that are skipped.\n * @param {BVH} bvh @param {ArrayLike<number>} o ray origin @param {ArrayLike<number>} d ray direction\n * @param {(triangle: number) => number} test\n */\nexport function walk(bvh, o, d, test) {\n const { boxes, nodes, order } = bvh\n const ix = 1 / d[0], iy = 1 / d[1], iz = 1 / d[2]\n // where the ray enters a node's box, or Infinity if it misses\n const enter = (n) => {\n const b = n * 6\n let t0 = (boxes[b] - o[0]) * ix, t1 = (boxes[b + 3] - o[0]) * ix\n let lo = Math.min(t0, t1), hi = Math.max(t0, t1)\n t0 = (boxes[b + 1] - o[1]) * iy; t1 = (boxes[b + 4] - o[1]) * iy\n lo = Math.max(lo, Math.min(t0, t1)); hi = Math.min(hi, Math.max(t0, t1))\n t0 = (boxes[b + 2] - o[2]) * iz; t1 = (boxes[b + 5] - o[2]) * iz\n lo = Math.max(lo, Math.min(t0, t1)); hi = Math.min(hi, Math.max(t0, t1))\n // NaN from a ray along a face counts as a hit - better a test too many than a miss\n return hi >= Math.max(lo, 0) || Number.isNaN(lo) || Number.isNaN(hi) ? Math.max(lo, 0) || 0 : Infinity\n }\n let best = Infinity\n // a box is worth opening if the ray enters it at all (a miss is Infinity - never worth it, even\n // before anything has been hit) and no further away than the nearest hit so far\n const worth = (t) => t !== Infinity && t <= best\n const root = enter(0)\n if (root === Infinity) return\n const stack = [0], at = [root]\n while (stack.length) {\n const n = /** @type {number} */ (stack.pop()), t = /** @type {number} */ (at.pop())\n if (t > best) continue\n const first = nodes[n * 2], count = nodes[n * 2 + 1]\n if (count) {\n for (let i = first; i < first + count; i++) best = Math.min(best, test(order[i]))\n continue\n }\n const a = enter(first), b = enter(first + 1)\n // the nearer child last, so it comes off the stack first\n if (a <= b) {\n if (worth(b)) { stack.push(first + 1); at.push(b) }\n if (worth(a)) { stack.push(first); at.push(a) }\n } else {\n if (worth(a)) { stack.push(first); at.push(a) }\n if (worth(b)) { stack.push(first + 1); at.push(b) }\n }\n }\n}\n","import * as mat3 from './math/mat3.js'\nimport * as mat4 from './math/mat4.js'\nimport { Ray } from './value/Ray.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { clipOwner, worldPlane } from './clip.js'\nimport { BVH_MIN_TRIANGLES, bvhOf, walk } from './geometry/bvh.js'\n\n/** @import { Camera } from './scene/cameras.js' */\n/** @import { Node } from './scene/Node.js' */\n/** @import { InstancedMesh, Lines, Mesh, Points } from './scene/drawables.js' */\n\n/** The section plane cutting what is being tested: world plane, and whether its cut faces are filled. @typedef {{ plane: Float32Array, cap: boolean }} Cut */\n/** @internal A surface ready for many rays: a mesh or one instance, with its world matrix and bounding sphere. @typedef {{ node: any, world: Float32Array, instance: number | null, cut: Cut | null, x: number, y: number, z: number, radius: number }} Solid */\n\n// Nodes are told apart by markers (drawMode, instanceMatrices) rather than instanceof, so picking\n// doesn't pull every node class into an app's bundle.\n\n/**\n * A pick result.\n * @typedef {object} Hit\n * @property {Node} node what was hit\n * @property {Vec3} point world position of the hit\n * @property {number} distance from the ray origin, world units\n * @property {Vec3 | null} normal world space face normal (meshes)\n * @property {number | null} face triangle index (meshes), vertex index (points), segment index (lines)\n * @property {number | null} instance instance index (InstancedMesh)\n * @property {[number, number] | null} uv texture coordinate at the hit (meshes with uvs)\n * @property {any} datum the node's data for what was hit: its row for an instance or point, or the\n * node's own data (null when it has none)\n */\n\nconst inverse = new Float32Array(16)\nconst instanceWorld = new Float32Array(16)\nconst a = new Vec3(), b = new Vec3(), c = new Vec3()\nconst localPlane = new Float32Array(4)\n\n/** The cut a node's nearest clip makes, or null. @param {Node | null} owner @returns {Cut | null} */\nconst cutBy = (owner) => (owner?.clip ? { plane: worldPlane(owner), cap: !!owner.clip.cap } : null)\n\n/**\n * Finds what a ray hits, on the CPU - no GPU read-back, so it also works in tests. Meshes are\n * tested against their triangles after a bounding sphere check; points and lines within a\n * tolerance in world units.\n */\nexport class Raycaster {\n ray = new Ray()\n near = 0\n far = Infinity\n /** How close (world units) a ray must pass to a point or line to hit it. */\n threshold = 0.1\n /** The camera it was aimed from (setFromCamera): what showFrom hides from it can't be hit. @type {Camera | null} */\n camera = null\n\n /**\n * Aim the ray through a position on screen.\n * @param {ArrayLike<number>} ndc [x, y] in normalised device coordinates, -1 to 1 (y up)\n * @param {Camera} camera\n * @returns {this}\n */\n setFromCamera(ndc, camera) {\n camera.updateWorld()\n this.camera = camera\n if (/** @type {any} */ (camera.constructor).type === 'orthographic-camera') {\n // parallel rays: from the near plane, straight through to the far one\n const inv = mat4.invert(new Float32Array(16), mat4.multiply(new Float32Array(16), camera.projectionMatrix, camera.viewMatrix))\n if (!inv) return this\n const near = new Vec3(ndc[0], ndc[1], -1).applyMatrix4(inv)\n this.ray.origin.copy(near)\n this.ray.direction.copy(new Vec3(ndc[0], ndc[1], 1).applyMatrix4(inv)).sub(near).normalize()\n return this\n }\n // from the camera along the pixel's line of sight, worked out in the camera's own space and\n // turned to the world - exact whatever the near and far planes (far: Infinity included)\n const p = camera.projectionMatrix, m = camera.worldMatrix\n const x = (ndc[0] + p[8]) / p[0], y = (ndc[1] + p[9]) / p[5]\n this.ray.origin.copy(camera.worldPosition)\n this.ray.direction.set(m[0] * x + m[4] * y - m[8], m[1] * x + m[5] * y - m[9], m[2] * x + m[6] * y - m[10]).normalize()\n return this\n }\n\n /**\n * Everything the ray hits, nearest first. Invisible and unpickable nodes (and their children)\n * are skipped, and so are those showFrom hides from the camera it was aimed from - only what is\n * drawn is hit. World matrices are brought up to date first.\n * @param {Node | Node[]} targets\n * @returns {Hit[]}\n */\n intersect(targets) {\n /** @type {Hit[]} */\n const hits = []\n for (const target of [targets].flat()) {\n target.updateWorld()\n // a clip above the target cuts it too\n this.#visit(target, hits, cutBy(clipOwner(target.parent)))\n }\n return hits.filter((h) => h.distance >= this.near && h.distance <= this.far).sort((x, y) => x.distance - y.distance)\n }\n\n /** @internal\n * The surfaces among what a frame drew that the ray meets, nearest first - its triangles, instanced\n * or not, cut as they were drawn. For questions about the picture just drawn, such as whether a\n * label is hidden behind something: what was drawn is the answer, pickable or not.\n * @param {import('./frame.js').DrawItem[]} items\n * @returns {Hit[]}\n */\n intersectDrawn(items) {\n /** @type {Hit[]} */\n const hits = []\n for (const item of items) {\n const n = /** @type {any} */ (item.node)\n if (n.drawMode !== 'triangles') continue\n const cut = item.clip ? { plane: item.clip.plane, cap: !!item.clip.cap } : null\n if (item.instances) {\n for (let i = 0; i < item.instances.count; i++) {\n mat4.multiply(instanceWorld, item.worldMatrix, item.instances.instanceMatrices.subarray(i * 16, i * 16 + 16))\n this.#mesh(n, instanceWorld, i, hits, cut)\n }\n } else this.#mesh(n, item.worldMatrix, null, hits, cut)\n }\n return hits.filter((h) => h.distance >= this.near && h.distance <= this.far).sort((x, y) => x.distance - y.distance)\n }\n\n /** @internal\n * The solid surfaces of a frame's draw list, ready for many rays: each mesh and each instance with its\n * world matrix and bounding sphere worked out once, rather than once per ray - for label occlusion,\n * which casts a ray per label.\n * @param {{ node: Node, worldMatrix: Float32Array, instances: { count: number, instanceMatrices: Float32Array } | null, clip: { plane: Float32Array, cap: unknown } | null }[]} items\n * @returns {Solid[]}\n */\n static solids(items) {\n /** @type {Solid[]} */\n const out = []\n for (const item of items) {\n const n = /** @type {any} */ (item.node)\n if (n.drawMode !== 'triangles' || !n.geometry.vertexCount) continue\n const box = n.geometry.bounds, center = box.getCenter(), radius = box.getRadius()\n const cut = item.clip ? { plane: item.clip.plane, cap: !!item.clip.cap } : null\n /** @param {Float32Array} world @param {number | null} instance */\n const add = (world, instance) => {\n const c = center.clone().applyMatrix4(world)\n const scale = Math.max(Math.hypot(world[0], world[1], world[2]), Math.hypot(world[4], world[5], world[6]), Math.hypot(world[8], world[9], world[10]))\n out.push({ node: n, world, instance, cut, x: c[0], y: c[1], z: c[2], radius: radius * scale })\n }\n if (item.instances) {\n for (let i = 0; i < item.instances.count; i++) {\n add(mat4.multiply(new Float32Array(16), item.worldMatrix, item.instances.instanceMatrices.subarray(i * 16, i * 16 + 16)), i)\n }\n } else add(Float32Array.from(item.worldMatrix), null)\n }\n return out\n }\n\n /** @internal\n * Whether the ray meets any of these solids nearer than `distance` - the first one found settles it,\n * so nothing is sorted. One node, or one instance of it, can be left out: what a label is on.\n * @param {Solid[]} solids from Raycaster.solids() @param {number} distance\n * @param {Node | null} [skip] @param {number | null} [skipInstance] null for the whole node\n * @returns {boolean}\n */\n blocked(solids, distance, skip = null, skipInstance = null) {\n const o = this.ray.origin, d = this.ray.direction\n /** @type {Hit[]} */\n const hits = []\n for (const s of solids) {\n if (s.node === skip && (skipInstance === null || s.instance === skipInstance)) continue\n // its bounding sphere first: missed, or wholly beyond the distance or behind the ray, it can't block\n const ox = s.x - o[0], oy = s.y - o[1], oz = s.z - o[2]\n const along = ox * d[0] + oy * d[1] + oz * d[2]\n const off = ox * ox + oy * oy + oz * oz - along * along, r2 = s.radius * s.radius\n if (off > r2) continue\n const half = Math.sqrt(r2 - off)\n if (along - half > distance || along + half < 0) continue\n hits.length = 0\n this.#mesh(s.node, s.world, s.instance, hits, s.cut)\n if (hits.length && hits[0].distance < distance) return true\n }\n return false\n }\n\n /** @internal\n * Where the ray meets one instance, point or segment of a drawable - the CPU half of GPU picking,\n * which finds what is under the pointer and leaves the exact point, face and uv to this.\n * @param {Node} node a Mesh, InstancedMesh, Points or Lines\n * @param {number} element the instance, point or segment (ignored for a plain Mesh)\n * @returns {Hit | null}\n */\n intersectElement(node, element) {\n node.updateWorld()\n const n = /** @type {any} */ (node)\n /** @type {Hit[]} */\n const hits = []\n const cut = cutBy(clipOwner(node))\n if (n.drawMode === 'triangles' && n.instanceMatrices) {\n if (element >= n.count) return null\n mat4.multiply(instanceWorld, n.worldMatrix, n.instanceMatrices.subarray(element * 16, element * 16 + 16))\n this.#mesh(n, instanceWorld, element, hits, cut)\n } else if (n.drawMode === 'triangles') {\n this.#mesh(n, n.worldMatrix, null, hits, cut)\n } else if (n.drawMode === 'points') {\n const p = n.geometry.positions\n if (element >= n.geometry.drawnVertices) return null\n const point = new Vec3(p[element * 3], p[element * 3 + 1], p[element * 3 + 2]).applyMatrix4(n.worldMatrix)\n hits.push({ node: n, point, distance: point.distanceTo(this.ray.origin), normal: null, face: element, instance: null, uv: null, datum: n.datumAt(element) })\n } else if (n.drawMode === 'lines') {\n const g = n.geometry, p = g.positions, idx = g.indices\n const i0 = idx ? idx[element * 2] : element * 2, i1 = idx ? idx[element * 2 + 1] : element * 2 + 1\n if (i1 >= g.vertexCount) return null\n a.set(p[i0 * 3], p[i0 * 3 + 1], p[i0 * 3 + 2]).applyMatrix4(n.worldMatrix)\n b.set(p[i1 * 3], p[i1 * 3 + 1], p[i1 * 3 + 2]).applyMatrix4(n.worldMatrix)\n const { t } = this.ray.distanceSqToSegment(a, b)\n hits.push({ node: n, point: this.ray.at(t), distance: t, normal: null, face: element, instance: null, uv: null, datum: n.datumAt(element) })\n }\n return hits[0] ?? null\n }\n\n /** @param {Node} node @param {Hit[]} hits @param {Cut | null} cut the plane cutting this subtree, from above */\n #visit(node, hits, cut) {\n if (!(this.camera ? node.shownTo(this.camera) : node.visible) || !node.pickable) return\n if (node.clip) cut = cutBy(node)\n const n = /** @type {any} */ (node)\n if (n.drawMode === 'triangles' && n.instanceMatrices) {\n for (let i = 0; i < n.count; i++) {\n mat4.multiply(instanceWorld, n.worldMatrix, n.instanceMatrices.subarray(i * 16, i * 16 + 16))\n this.#mesh(n, instanceWorld, i, hits, cut)\n }\n } else if (n.drawMode === 'triangles') {\n this.#mesh(n, n.worldMatrix, null, hits, cut)\n } else if (n.drawMode === 'points') {\n this.#points(n, hits)\n } else if (n.drawMode === 'lines') {\n this.#lines(n, hits)\n }\n for (const child of node.children) this.#visit(child, hits, cut)\n }\n\n /**\n * @param {Mesh} mesh @param {Float32Array} world @param {number | null} instance @param {Hit[]} hits\n * @param {Cut | null} [cut] what is past it isn't there; with a cap, the faces behind the cut are\n */\n #mesh(mesh, world, instance, hits, cut = null) {\n const g = mesh.geometry\n if (!g.vertexCount) return\n // cheap rejection first\n const box = g.bounds\n const center = box.getCenter().applyMatrix4(world)\n const scale = Math.max(Math.hypot(world[0], world[1], world[2]), Math.hypot(world[4], world[5], world[6]), Math.hypot(world[8], world[9], world[10]))\n if (this.ray.intersectSphere(center, box.getRadius() * scale) === null) return\n if (!mat4.invert(inverse, world)) return\n\n // test in the mesh's own space, then report in world space\n const local = this.ray.clone().applyMatrix4(inverse)\n const p = g.positions, idx = g.indices\n // a cap shows the backs of faces through the cut, so they can be hit too\n const cullBack = !mesh.material.doubleSided && !cut?.cap\n // the plane in the mesh's own space: [n, d] times the world matrix\n if (cut) for (let j = 0; j < 4; j++) localPlane[j] = cut.plane[0] * world[j * 4] + cut.plane[1] * world[j * 4 + 1] + cut.plane[2] * world[j * 4 + 2] + cut.plane[3] * world[j * 4 + 3]\n const o = local.origin, d = local.direction\n let best = null, bestT = Infinity, bestFace = -1\n /** @param {number} f a triangle @returns {number} the nearest hit so far */\n const test = (f) => {\n const i0 = idx ? idx[f * 3] : f * 3, i1 = idx ? idx[f * 3 + 1] : f * 3 + 1, i2 = idx ? idx[f * 3 + 2] : f * 3 + 2\n a.set(p[i0 * 3], p[i0 * 3 + 1], p[i0 * 3 + 2])\n b.set(p[i1 * 3], p[i1 * 3 + 1], p[i1 * 3 + 2])\n c.set(p[i2 * 3], p[i2 * 3 + 1], p[i2 * 3 + 2])\n const hit = local.intersectTriangle(a, b, c, cullBack)\n // a hit on the cut-away side isn't there\n if (hit && cut && localPlane[0] * (o[0] + d[0] * hit.t) + localPlane[1] * (o[1] + d[1] * hit.t) + localPlane[2] * (o[2] + d[2] * hit.t) + localPlane[3] > 0) return bestT\n if (hit && (hit.t < bestT || (hit.t === bestT && f < bestFace))) {\n best = { ...hit, i0, i1, i2 }\n bestT = hit.t\n bestFace = f\n }\n return bestT\n }\n const triangles = Math.floor(g.drawnCount / 3)\n // big meshes through their tree; small ones a triangle at a time\n if (triangles >= BVH_MIN_TRIANGLES) walk(bvhOf(g, triangles), o, d, test)\n else for (let f = 0; f < triangles; f++) test(f)\n if (!best) return\n\n let point = local.at(best.t).applyMatrix4(world)\n // face normal from the local triangle, into world space with the normal matrix\n a.set(p[best.i0 * 3], p[best.i0 * 3 + 1], p[best.i0 * 3 + 2])\n b.set(p[best.i1 * 3], p[best.i1 * 3 + 1], p[best.i1 * 3 + 2]).sub(a)\n c.set(p[best.i2 * 3], p[best.i2 * 3 + 1], p[best.i2 * 3 + 2]).sub(a)\n const n = b.clone().cross(c)\n const normalMatrix = mat3.normalFromMat4(new Float32Array(9), world)\n let normal = normalMatrix ? new Vec3(\n normalMatrix[0] * n[0] + normalMatrix[3] * n[1] + normalMatrix[6] * n[2],\n normalMatrix[1] * n[0] + normalMatrix[4] * n[1] + normalMatrix[7] * n[2],\n normalMatrix[2] * n[0] + normalMatrix[5] * n[1] + normalMatrix[8] * n[2]).normalize() : null\n // a face seen from behind through a capped cut: what was hit is the cut face, on the plane\n if (cut?.cap && normal && normal.dot(this.ray.direction) > 0) {\n const P = cut.plane, { origin, direction } = this.ray\n const across = P[0] * direction[0] + P[1] * direction[1] + P[2] * direction[2]\n if (across < 0) point = this.ray.at(-(P[0] * origin[0] + P[1] * origin[1] + P[2] * origin[2] + P[3]) / across)\n normal = new Vec3(P[0], P[1], P[2])\n }\n\n /** @type {[number, number] | null} */\n let uv = null\n if (g.uvs) {\n const w = 1 - best.u - best.v, t = g.uvs\n uv = [\n w * t[best.i0 * 2] + best.u * t[best.i1 * 2] + best.v * t[best.i2 * 2],\n w * t[best.i0 * 2 + 1] + best.u * t[best.i1 * 2 + 1] + best.v * t[best.i2 * 2 + 1],\n ]\n }\n // a row per vertex (a surface): the row of the hit triangle's nearest corner\n let datum = mesh.datumAt(instance)\n if (instance === null && Array.isArray(mesh.data) && mesh.data.length === g.vertexCount) {\n const w0 = 1 - best.u - best.v\n datum = mesh.data[w0 >= best.u && w0 >= best.v ? best.i0 : best.u >= best.v ? best.i1 : best.i2] ?? null\n }\n hits.push({ node: mesh, point, distance: point.distanceTo(this.ray.origin), normal, face: bestFace, instance, uv, datum })\n }\n\n /** @param {Points} node @param {Hit[]} hits */\n #points(node, hits) {\n const p = node.geometry.positions, w = node.worldMatrix\n const limit = this.threshold * this.threshold\n let best = null\n for (let i = 0, n = node.geometry.drawnVertices; i < n; i++) {\n a.set(p[i * 3], p[i * 3 + 1], p[i * 3 + 2]).applyMatrix4(w)\n const { distanceSq } = this.ray.distanceSqToPoint(a)\n if (distanceSq > limit) continue\n const distance = a.distanceTo(this.ray.origin)\n if (!best || distance < best.distance) best = { node, point: a.clone(), distance, normal: null, face: i, instance: null, uv: null, datum: node.datumAt(i) }\n }\n if (best) hits.push(best)\n }\n\n /** @param {Lines} node @param {Hit[]} hits */\n #lines(node, hits) {\n const g = node.geometry, p = g.positions, idx = g.indices, w = node.worldMatrix\n const limit = this.threshold * this.threshold\n let best = null\n for (let s = 0, n = Math.floor(g.drawnCount / 2); s < n; s++) {\n const i0 = idx ? idx[s * 2] : s * 2, i1 = idx ? idx[s * 2 + 1] : s * 2 + 1\n a.set(p[i0 * 3], p[i0 * 3 + 1], p[i0 * 3 + 2]).applyMatrix4(w)\n b.set(p[i1 * 3], p[i1 * 3 + 1], p[i1 * 3 + 2]).applyMatrix4(w)\n const { distanceSq, t } = this.ray.distanceSqToSegment(a, b)\n if (distanceSq > limit) continue\n if (!best || t < best.distance) best = { node, point: this.ray.at(t), distance: t, normal: null, face: s, instance: null, uv: null, datum: node.datumAt(s) }\n }\n if (best) hits.push(best)\n }\n}\n","// Picking an area of the canvas: everything whose place on screen falls inside a box or a lasso drawn\n// over it - each point, instance and line segment on its own, and a mesh by its middle. Positions\n// are tested, not surfaces, so what is hidden behind other things is found too: selecting a region\n// of a scatter takes the whole region, front to back.\nimport * as mat4 from './math/mat4.js'\nimport { hiddenInstance } from './scene/drawables.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { describe, fail } from './validate.js'\n\n/** @import { Hit } from './Raycaster.js' */\n/** @import { Node } from './scene/Node.js' */\n/** @import { Camera } from './scene/cameras.js' */\n\n/**\n * A box on the canvas, CSS pixels from its top left - width and height may be negative, as a drag\n * up or left makes them - or a lasso: the points of a polygon, [x, y] each.\n * @typedef {{ x: number, y: number, width: number, height: number } | [number, number][]} PickArea\n */\n\nconst instanceWorld = new Float32Array(16)\n\n/**\n * The polygon an area is, and its bounding box, for the inside test.\n * @param {PickArea} area\n * @returns {{ points: number[], left: number, top: number, right: number, bottom: number }}\n */\nfunction outline(area) {\n /** @type {number[]} */\n let points\n if (Array.isArray(area)) {\n if (area.length < 3 || !area.every((p) => Array.isArray(p) && p.length === 2 && p.every(Number.isFinite))) {\n fail('View', `pickArea() takes a box { x, y, width, height } or a lasso of three or more [x, y] points, got ${describe(area)}`)\n }\n points = area.flat()\n } else {\n const { x, y, width, height } = area ?? /** @type {any} */ ({})\n if (![x, y, width, height].every(Number.isFinite)) {\n fail('View', `pickArea() takes a box { x, y, width, height } or a lasso of three or more [x, y] points, got ${describe(area)}`)\n }\n points = [x, y, x + width, y, x + width, y + height, x, y + height]\n }\n let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity\n for (let i = 0; i < points.length; i += 2) {\n left = Math.min(left, points[i])\n right = Math.max(right, points[i])\n top = Math.min(top, points[i + 1])\n bottom = Math.max(bottom, points[i + 1])\n }\n return { points, left, top, right, bottom }\n}\n\n/** Is (x, y) inside the polygon? Even-odd crossings. @param {number[]} p @param {number} x @param {number} y */\nfunction inside(p, x, y) {\n let into = false\n for (let i = 0, j = p.length - 2; i < p.length; j = i, i += 2) {\n const yi = p[i + 1], yj = p[j + 1]\n if ((yi > y) !== (yj > y) && x < p[i] + (p[j] - p[i]) * (y - yi) / (yj - yi)) into = !into\n }\n return into\n}\n\n/**\n * Everything in the scene the camera shows, pickable, whose place falls inside the area - nearest\n * the camera first.\n * @param {Node} scene @param {Camera} camera @param {Float32Array} viewProjection\n * @param {number} width @param {number} height the canvas, CSS pixels\n * @param {PickArea} area\n * @returns {Hit[]}\n */\nexport function pickArea(scene, camera, viewProjection, width, height, area) {\n const shape = outline(area)\n const eye = camera.worldPosition\n const m = viewProjection\n /** @type {Hit[]} */\n const hits = []\n /** World position (x, y, z) inside the area? @param {number} x @param {number} y @param {number} z */\n const within = (x, y, z) => {\n const w = m[3] * x + m[7] * y + m[11] * z + m[15]\n if (w <= 0) return false\n const nz = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w\n if (nz < -1 || nz > 1) return false\n const sx = ((m[0] * x + m[4] * y + m[8] * z + m[12]) / w * 0.5 + 0.5) * width\n const sy = (0.5 - (m[1] * x + m[5] * y + m[9] * z + m[13]) / w * 0.5) * height\n return sx >= shape.left && sx <= shape.right && sy >= shape.top && sy <= shape.bottom && inside(shape.points, sx, sy)\n }\n /** @param {any} node @param {number} x @param {number} y @param {number} z @param {number | null} face @param {number | null} instance */\n const hit = (node, x, y, z, face, instance) => {\n const point = new Vec3(x, y, z)\n hits.push({ node, point, distance: point.distanceTo(eye), normal: null, face, instance, uv: null, datum: node.datumAt(instance ?? face) })\n }\n const p = new Vec3()\n\n /** @param {Node} node */\n const visit = (node) => {\n if (!node.shownTo(camera) || !node.pickable) return\n const n = /** @type {any} */ (node)\n if (n.isDrawable && n.geometry.vertexCount) {\n const g = n.geometry, world = n.worldMatrix\n if (n.drawMode === 'points') {\n const pos = g.positions\n for (let i = 0; i < g.drawnVertices; i++) {\n p.set(pos[i * 3], pos[i * 3 + 1], pos[i * 3 + 2]).applyMatrix4(world)\n if (within(p[0], p[1], p[2])) hit(n, p[0], p[1], p[2], i, null)\n }\n } else if (n.drawMode === 'lines') {\n // a segment by its middle\n const pos = g.positions, idx = g.indices\n for (let s = 0; s < Math.floor(g.drawnCount / 2); s++) {\n const a = idx ? idx[s * 2] : s * 2, b = idx ? idx[s * 2 + 1] : s * 2 + 1\n p.set((pos[a * 3] + pos[b * 3]) / 2, (pos[a * 3 + 1] + pos[b * 3 + 1]) / 2, (pos[a * 3 + 2] + pos[b * 3 + 2]) / 2).applyMatrix4(world)\n if (within(p[0], p[1], p[2])) hit(n, p[0], p[1], p[2], s, null)\n }\n } else if (n.instanceMatrices) {\n // each instance by the middle of its copy of the geometry; hidden ones aren't there\n const centre = g.bounds.getCenter()\n for (let i = 0; i < n.count; i++) {\n if (hiddenInstance(n.instanceMatrices, i)) continue\n mat4.multiply(instanceWorld, world, n.instanceMatrices.subarray(i * 16, i * 16 + 16))\n p.copy(centre).applyMatrix4(instanceWorld)\n if (within(p[0], p[1], p[2])) hit(n, p[0], p[1], p[2], null, i)\n }\n } else {\n p.copy(g.bounds.getCenter()).applyMatrix4(world)\n if (within(p[0], p[1], p[2])) hit(n, p[0], p[1], p[2], null, null)\n }\n }\n for (const child of node.children) visit(child)\n }\n visit(scene)\n return hits.sort((a, b) => a.distance - b.distance)\n}\n","// Change detection for on-demand rendering. Each frame the View lays out a flat signature of\n// everything that affects the picture - transforms, visibility, geometry and instance versions,\n// material values, lights, labels, the camera - and draws only when it differs from the last one.\n// It costs a few numbers per node, so an idle view does almost no work.\n\n/** @import { Scene } from './scene/Scene.js' */\n/** @import { Camera } from './scene/cameras.js' */\n\n// object identity as a number, so swapping a geometry, material or texture counts as a change\n/** @type {WeakMap<object, number>} */\nconst ids = new WeakMap()\nlet nextId = 1\n/** @param {object} o */\nconst idOf = (o) => {\n let id = ids.get(o)\n if (id === undefined) ids.set(o, id = nextId++)\n return id\n}\n\nexport class ChangeWatch {\n #values = new Float64Array(256)\n #previous = new Float64Array(256)\n #count = 0\n #previousCount = -1\n /** @type {string[]} */ #strings = []\n /** @type {string[]} */ #previousStrings = []\n\n /**\n * Has anything that affects the picture changed since the last call? The first call says yes.\n * @param {Scene} scene\n * @param {Camera} camera\n * @returns {boolean}\n */\n changed(scene, camera) {\n this.#count = 0\n this.#strings = []\n this.#camera(camera)\n this.#scene(scene, camera)\n\n let changed = this.#count !== this.#previousCount || this.#strings.length !== this.#previousStrings.length\n for (let i = 0; !changed && i < this.#count; i++) changed = this.#values[i] !== this.#previous[i]\n for (let i = 0; !changed && i < this.#strings.length; i++) changed = this.#strings[i] !== this.#previousStrings[i]\n\n // keep this signature as the one to compare against next time\n ;[this.#previous, this.#values] = [this.#values, this.#previous]\n this.#previousCount = this.#count\n this.#previousStrings = this.#strings\n return changed\n }\n\n /** Forget the last signature, so the next check reports a change. */\n reset() {\n this.#previousCount = -1\n }\n\n /** @param {number} v */\n #push(v) {\n if (this.#count === this.#values.length) {\n const grown = new Float64Array(this.#values.length * 2)\n grown.set(this.#values)\n this.#values = grown\n const previous = new Float64Array(grown.length)\n previous.set(this.#previous)\n this.#previous = previous\n }\n this.#values[this.#count++] = v\n }\n\n /** @param {ArrayLike<number>} a */\n #pushAll(a) {\n for (let i = 0; i < a.length; i++) this.#push(a[i])\n }\n\n /** @param {any} camera */\n #camera(camera) {\n this.#push(idOf(camera))\n this.#pushAll(camera.position)\n this.#pushAll(camera.quaternion)\n if (camera.target) this.#pushAll(camera.target)\n this.#push(camera.fov ?? camera.height)\n this.#push(camera.near)\n this.#push(camera.far)\n this.#push(camera.aspect)\n }\n\n /** @param {any} scene @param {any} camera */\n #scene(scene, camera) {\n const bg = scene.background\n if (!bg) this.#push(-1)\n else if ('getHex' in bg) this.#pushAll(bg)\n else this.#texture(bg)\n const env = scene.environment\n if (typeof env === 'string') this.#strings.push(env)\n else this.#texture(env)\n this.#push(scene.environmentIntensity)\n this.#push(scene.backgroundBlur)\n const fog = scene.fog\n if (fog) {\n this.#pushAll(fog.color)\n this.#push(fog.density)\n this.#push(fog.near)\n this.#push(fog.far)\n } else this.#push(-1)\n this.#node(scene, camera)\n }\n\n /** @param {any} node @param {any} camera */\n #node(node, camera) {\n this.#push(idOf(node))\n const shown = node.shownTo(camera)\n this.#push(shown ? 1 : 0)\n // subtrees this camera doesn't draw don't matter until they show again\n if (!shown) return\n this.#push(node.overlay ? idOf(node.overlay) : 0)\n // a section plane moving or changing colour\n const clip = node.clip\n if (clip) {\n this.#pushAll(clip.normal)\n this.#push(clip.offset)\n this.#push(clip.cap ? clip.cap.getHex() : -1)\n } else this.#push(-2)\n // which pointer handlers it has: the frame says whether anything can be clicked or dragged\n this.#push((node.handlersFor('click').length ? 1 : 0) | (node.handlersFor('hover').length ? 2 : 0) | (node.tooltip ? 4 : 0) | (node.onDrag ? 8 : 0) | (node.highlightWhole ? 16 : 0))\n // what hovering tints it with - a different colour shows straight away on what is hovered\n if (node.highlight) this.#pushAll(node.highlight)\n else this.#push(node.highlight === false ? -5 : -4)\n const outline = node.outline\n if (outline) {\n this.#pushAll(outline.color)\n this.#push(outline.width)\n } else this.#push(-3)\n this.#pushAll(node.position)\n this.#pushAll(node.quaternion)\n this.#pushAll(node.scale)\n // a node that keeps its own matrix is moved by editing it\n if (!node.matrixAutoUpdate) this.#pushAll(node.matrix)\n if (node.isDrawable) this.#drawable(node)\n else if (node.isLabel) this.#label(node)\n else if (node.lightKind) this.#light(node)\n for (const child of node.children) this.#node(child, camera)\n }\n\n /** @param {any} node */\n #drawable(node) {\n const g = node.geometry, m = node.material\n this.#push(idOf(g))\n this.#push(g.version)\n this.#push(g.drawCount ?? -1)\n this.#push(node.renderOrder)\n this.#push((node.castShadow ? 1 : 0) | (node.receiveShadow ? 2 : 0) | (node.sort ? 4 : 0))\n if ('arrowBits' in node) {\n this.#push(node.arrowBits)\n this.#push(node.arrowSize)\n }\n // per-instance labels come from these, so swapping either redraws\n this.#push(node.labels ? idOf(node.labels) : 0)\n this.#push(node.data && typeof node.data === 'object' ? idOf(node.data) : 0)\n if ('instanceMatrices' in node) {\n this.#push(node.count)\n this.#push(node.version)\n }\n this.#push(idOf(m))\n this.#pushAll(m.color)\n this.#pushAll(m.emissive)\n this.#push(m.emissiveIntensity)\n this.#push(m.opacity)\n this.#push(m.roughness)\n this.#push(m.metalness)\n this.#push(m.size)\n this.#push(m.width)\n this.#push(m.dash)\n this.#push(m.gap)\n this.#push(m.dashOffset)\n this.#push(m.alphaTest)\n this.#push(m.normalScale)\n this.#push(m.aoMapIntensity)\n this.#push(m.triplanar)\n this.#push(m.bumpScale)\n this.#push(m.transmission)\n this.#push(m.clearcoat)\n this.#push(m.clearcoatRoughness)\n this.#push(m.sheen)\n this.#pushAll(m.sheenColor)\n this.#push(m.sheenRoughness)\n this.#push(m.ior)\n this.#push(m.specularIntensity)\n this.#pushAll(m.specularColor)\n this.#push(m.anisotropy)\n this.#push(m.anisotropyRotation)\n this.#push(m.translucency)\n this.#push(m.toon)\n this.#push(m.lightMapIntensity)\n this.#push(m.environmentIntensity)\n this.#pushAll(m.translucencyColor)\n this.#push((m.unlit ? 1 : 0) | (m.flatShading ? 2 : 0) | (m.doubleSided ? 4 : 0) | (m.vertexColors ? 8 : 0) |\n (m.depthWrite ? 16 : 0) | (m.depthTest ? 32 : 0) | (m.sizeAttenuation ? 64 : 0) | (m.blending === 'additive' ? 128 : m.blending === 'multiply' ? 1024 : 0) | (m.transparent ? 256 : 0) | (m.fog ? 512 : 0))\n for (const [, texture] of m.textures) this.#texture(texture)\n }\n\n /** @param {any} texture */\n #texture(texture) {\n this.#push(idOf(texture))\n this.#push(texture.version)\n this.#pushAll(texture.repeat)\n this.#push(texture.rotation)\n this.#pushAll(texture.center)\n this.#push(texture.uvSet)\n this.#pushAll(texture.offset)\n }\n\n /** @param {any} label */\n #label(label) {\n this.#strings.push(label.text, label.className, label.place, label.overlap, label.edge ?? '')\n this.#pushAll(label.offset)\n this.#push(label.priority)\n this.#push(label.occlude ? 1 : 0)\n this.#push(label.leader ? 1 : 0)\n this.#push(label.minScale)\n }\n\n /** @param {any} light */\n #light(light) {\n this.#pushAll(light.color)\n this.#push(light.intensity)\n if (light.ground) this.#pushAll(light.ground)\n if (light.direction) this.#pushAll(light.direction)\n if (light.target) this.#pushAll(light.target)\n if (light.castShadow) this.#push(1)\n if (light.shadowBounds) {\n this.#pushAll(light.shadowBounds.min)\n this.#pushAll(light.shadowBounds.max)\n }\n if ('range' in light) this.#push(light.range)\n if ('angle' in light) {\n this.#push(light.angle)\n this.#push(light.penumbra)\n }\n }\n}\n","// Fog: what is further away fades into a colour - a misty harbour, a hazy city, depth in a big\n// scene. Set a scene's fog and its background to the same colour, and distant things melt into it.\nimport { Color } from './value/Color.js'\nimport { checkNumber, checkOptions, describe, fail } from './validate.js'\n\n/** @import { ColorInput } from './types.js' */\n\n/**\n * @typedef {object} FogOptions\n * @property {ColorInput} [color] what distant things fade to - usually the background (default '#808080')\n * @property {number} [density] exponential fog, thickening with distance, as mist does: about how much\n * it hides per unit of distance (try 0.02 - 0.1). The default, unless near and far are given (0.05)\n * @property {number} [near] linear fog instead: the distance it starts at\n * @property {number} [far] linear fog: the distance where everything is fog colour\n */\n\nexport const FOG_OPTIONS = ['color', 'density', 'near', 'far']\nexport const FOG_HINTS = {\n start: \"use 'near' for where linear fog starts\",\n end: \"use 'far' for where linear fog is complete\",\n type: \"give 'density' for exponential fog, or 'near' and 'far' for linear\",\n exp2: \"give 'density' for exponential fog\",\n colour: \"use 'color'\",\n}\n\n/** A scene's fog: change its numbers in place to thicken or thin it. */\nexport class Fog {\n /** What distant things fade to. @type {Color} */ color = new Color(0x808080)\n /** Exponential fog's density, or 0 when the fog is linear. */ density = 0.05\n /** Linear fog: where it starts. */ near = 0\n /** Linear fog: where it is complete. */ far = 100\n\n /** @param {FogOptions} [options] */\n constructor(options = {}) {\n checkOptions('fog', options, FOG_OPTIONS, FOG_HINTS)\n if (options.color !== undefined) this.color.set(options.color, 'fog')\n const linear = options.near !== undefined || options.far !== undefined\n if (linear && options.density !== undefined) fail('fog', \"give 'density' for exponential fog, or 'near' and 'far' for linear - not both\")\n if (linear) {\n this.density = 0\n if (options.near !== undefined) this.near = checkNumber('fog', 'near', options.near)\n if (options.far !== undefined) this.far = checkNumber('fog', 'far', options.far)\n if (!(this.near >= 0) || !(this.far > this.near)) fail('fog', `'near' must be 0 or more and 'far' beyond it, got near ${this.near}, far ${this.far}`)\n } else if (options.density !== undefined) {\n this.density = checkNumber('fog', 'density', options.density)\n if (!(this.density > 0)) fail('fog', `'density' must be more than 0, got ${this.density}`)\n }\n }\n\n /** Linear (near to far) rather than exponential (density)? */\n get linear() {\n return this.density === 0\n }\n\n /** @internal\n * A Fog from a Fog (returned as is) or options.\n * @param {Fog | FogOptions} input @param {string} [owner]\n * @returns {Fog}\n */\n static fromInput(input, owner = 'fog') {\n if (input instanceof Fog) return input\n if (!input || typeof input !== 'object' || Array.isArray(input)) fail(owner, `'fog' must be { color, density } or { color, near, far }, or null, got ${describe(input)}`)\n return new Fog(input)\n }\n\n /** @returns {FogOptions} */\n toJSON() {\n const color = this.color.getStyle()\n return this.linear ? { color, near: this.near, far: this.far } : { color, density: this.density }\n }\n}\n","import { Color } from '../value/Color.js'\nimport { Texture } from '../material/Texture.js'\nimport { checkNumber, describe, fail } from '../validate.js'\nimport { Fog } from '../fog.js'\nimport { NODE_OPTIONS, Node } from './Node.js'\n\n/** @import { NodeOptions } from './Node.js' */\n/** @import { ColorInput } from '../types.js' */\n/** @import { TextureOptions } from '../material/Texture.js' */\n/** @import { FogOptions } from '../fog.js' */\n\n/** @typedef {'studio' | 'none'} EnvironmentPreset */\n\n/**\n * @typedef {NodeOptions & {\n * background?: ColorInput | Texture | TextureOptions | null,\n * environment?: EnvironmentPreset | string | Texture | TextureOptions,\n * environmentIntensity?: number,\n * backgroundBlur?: number,\n * fog?: FogOptions | Fog | null,\n * }} SceneOptions\n */\n\n/**\n * The root of everything drawn. Each frame the View (or your own loop) calls update() and the\n * renderer draws what it holds.\n */\nexport class Scene extends Node {\n static type = 'scene'\n static get OPTIONS() { return [...NODE_OPTIONS, 'background', 'environment', 'environmentIntensity', 'backgroundBlur', 'fog'] }\n static HINTS = {\n fogColor: \"use fog: { color, density }\",\n lights: \"add lights as children: scene.add(new DirectionalLight({ ... }))\",\n envMap: \"use 'environment': 'studio', or an .hdr url\",\n environmentMap: \"use 'environment': 'studio', or an .hdr url\",\n backgroundBlurriness: \"use 'backgroundBlur' (0-1)\",\n }\n\n /** @type {Color | Texture | null} null = transparent */\n #background = null\n /** Image-based lighting for materials. @type {EnvironmentPreset | Texture} */\n #environment = 'none'\n /** Scales the environment's light. */\n environmentIntensity = 1\n /** 0-1: how blurred a panorama background is drawn - a soft backdrop that doesn't compete. */\n backgroundBlur = 0\n /** @internal Set by the View drawing it, from its reducedMotion: charts' transitions and flows stand still. */\n motionReduced = false\n /** @type {Fog | null} */\n #fog = null\n\n /** @param {SceneOptions} [options] */\n constructor(options = {}) {\n super(options)\n if (options.background !== undefined) this.#setBackground(options.background)\n if (options.environment !== undefined) this.#setEnvironment(options.environment)\n if (options.environmentIntensity !== undefined) this.environmentIntensity = /** @type {number} */ (checkNumber('Scene', 'environmentIntensity', options.environmentIntensity))\n if (options.backgroundBlur !== undefined) this.backgroundBlur = /** @type {number} */ (checkNumber('Scene', 'backgroundBlur', options.backgroundBlur))\n if (options.fog != null) this.#fog = Fog.fromInput(options.fog, 'Scene')\n }\n\n /**\n * Distance fog, or null for none: set { color, density } (exponential, like mist) or\n * { color, near, far } (linear). Give the background the same colour, so distant things melt into\n * it; change its numbers in place to thicken or thin it. Materials with fog: false ignore it.\n * @returns {Fog | null}\n */\n get fog() { return this.#fog }\n /** @param {FogOptions | Fog | null} v */\n set fog(v) {\n this.#fog = v == null ? null : Fog.fromInput(v, 'Scene')\n }\n\n /**\n * A colour, a panorama (an equirectangular texture - often the environment itself), or null for\n * transparent. Assign any colour input. @returns {Color | Texture | null}\n */\n get background() { return this.#background }\n /** @param {ColorInput | Texture | TextureOptions | null} v */\n set background(v) {\n this.#setBackground(v)\n }\n\n /** @param {ColorInput | Texture | TextureOptions | null} v */\n #setBackground(v) {\n if (v == null) this.#background = null\n else if (v instanceof Texture) this.#background = v\n else if (typeof v === 'object' && !Array.isArray(v) && !ArrayBuffer.isView(v)) this.#background = new Texture(/** @type {TextureOptions} */ (v))\n else this.#background = Color.fromInput(/** @type {ColorInput} */ (v), 'Scene')\n }\n\n /**\n * Light from all around, reflected by every lit material: 'studio' (built in, no download),\n * 'none', or an equirectangular HDR image - a .hdr url or a Texture. @returns {EnvironmentPreset | Texture}\n */\n get environment() { return this.#environment }\n /** @param {EnvironmentPreset | string | Texture | TextureOptions} v */\n set environment(v) {\n this.#setEnvironment(v)\n }\n\n /** @param {EnvironmentPreset | string | Texture | TextureOptions} v */\n #setEnvironment(v) {\n if (v === 'studio' || v === 'none') this.#environment = v\n else if (typeof v === 'string' && /[./]/.test(v)) this.#environment = new Texture({ url: v, colorSpace: 'linear', mipmaps: false })\n else if (v instanceof Texture) this.#environment = v\n else if (v && typeof v === 'object') this.#environment = new Texture({ colorSpace: 'linear', mipmaps: false, .../** @type {TextureOptions} */ (v) })\n else fail('Scene', `'environment' must be 'studio', 'none', an .hdr url or a texture, got ${describe(v)}`)\n }\n\n /**\n * Advance one frame: run onUpdate handlers depth first, apply any removals they queued, then\n * bring every world matrix up to date.\n * @param {number} dt seconds since the last frame\n * @param {number} t seconds since the start\n * @returns {this}\n */\n update(dt, t) {\n runHandlers(this, dt, t, new Set())\n this.updateWorldTree()\n return this\n }\n\n /** Resolves when every texture in the scene has loaded. @returns {Promise<void>} */\n get ready() {\n /** @type {Promise<unknown>[]} */\n const waits = []\n if (this.#background instanceof Texture) waits.push(this.#background.ready)\n if (this.#environment instanceof Texture) waits.push(this.#environment.ready)\n this.traverse((n) => /** @type {any} */ (n).isDrawable && waits.push(/** @type {any} */ (n).material.ready()))\n return Promise.all(waits).then(() => {})\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), background: this.#background, environment: this.#environment,\n environmentIntensity: this.environmentIntensity, backgroundBlur: this.backgroundBlur, fog: this.#fog ? this.#fog.toJSON() : null }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = {}\n if (this.#background) {\n const bg = this.#background instanceof Texture ? this.#background.toJSON() : this.#background.toJSON()\n if (bg) json.background = bg\n }\n if (this.#environment !== 'none') {\n const env = typeof this.#environment === 'string' ? this.#environment : this.#environment.toJSON()\n if (env) json.environment = env\n }\n if (this.environmentIntensity !== 1) json.environmentIntensity = this.environmentIntensity\n if (this.backgroundBlur) json.backgroundBlur = this.backgroundBlur\n if (this.#fog) json.fog = this.#fog.toJSON()\n return json\n }\n}\n\n// Handlers run for invisible nodes too - behaviour may be what makes them visible again. Each\n// node's children are copied before they are walked, so handlers can add, remove and move nodes -\n// themselves included - without the walk skipping or losing one; a node that moves to a parent\n// walked later still runs once a frame.\n/** @param {Node} node @param {number} dt @param {number} t @param {Set<Node>} ran */\nfunction runHandlers(node, dt, t, ran) {\n if (node.hasHandlers && !ran.has(node)) {\n ran.add(node)\n node.runHandlers(dt, t)\n }\n const children = node.children\n if (children.length) for (const child of [...children]) runHandlers(child, dt, t, ran)\n}\n","import { Color } from '../value/Color.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { Box3 } from '../value/Box3.js'\nimport { checkNumber, describe, fail } from '../validate.js'\nimport { NODE_OPTIONS, Node, inParentSpace, setPoint } from './Node.js'\n\n/** @import { NodeOptions } from './Node.js' */\n/** @import { Box3Input, ColorInput, Vec3Input } from '../types.js' */\n\n/** @typedef {NodeOptions & { color?: ColorInput, intensity?: number }} LightOptions */\n/** @typedef {'ambient' | 'hemisphere' | 'directional' | 'point' | 'spot'} LightKind */\n\nconst LIGHT_OPTIONS = [...NODE_OPTIONS, 'color', 'intensity']\nconst LIGHT_HINTS = {\n distance: \"use 'range' (0 = infinite)\",\n decay: 'falloff is physical (inverse square), as in glTF - limit it with range',\n attenuation: \"use 'range' - falloff is physical (inverse square)\",\n shadow: \"use 'castShadow: true' (directional, spot and point lights)\",\n}\n\n/**\n * Base for lights. Colour and intensity follow glTF's KHR_lights_punctual, so loaded scenes light\n * the same; colours are ordinary colour inputs, the same as materials.\n */\nexport class Light extends Node {\n static OPTIONS = LIGHT_OPTIONS\n static HINTS = LIGHT_HINTS\n /** @internal What kind of light, for renderers - read without importing every light class. @type {LightKind} */\n static kind = 'ambient'\n\n /** @internal @returns {LightKind} */\n get lightKind() {\n return /** @type {typeof Light} */ (this.constructor).kind\n }\n\n #color = new Color(0xffffff)\n intensity = 1\n\n /** @param {LightOptions} [options] */\n constructor(options = {}) {\n super(options)\n const owner = this.constructor.name\n if (options.color !== undefined) this.#color.set(options.color, owner)\n if (options.intensity !== undefined) {\n this.intensity = checkNumber(owner, 'intensity', options.intensity)\n if (this.intensity < 0) fail(owner, `'intensity' can't be negative, got ${this.intensity}`)\n }\n }\n\n /** @returns {Color} */\n get color() { return this.#color }\n /** @param {ColorInput} v */\n set color(v) { this.#color.set(v, this.constructor.name) }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), color: this.#color.clone(), intensity: this.intensity }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = {}\n if (this.#color.getHex() !== 0xffffff) json.color = this.#color.getStyle()\n if (this.intensity !== 1) json.intensity = this.intensity\n return json\n }\n}\n\n/** Light from everywhere equally: lifts the shadows. */\nexport class AmbientLight extends Light {\n static type = 'ambient-light'\n /** @internal @type {LightKind} */\n static kind = 'ambient'\n}\n\n/** Cheap outdoor fill: sky colour from above blending to ground colour from below. */\nexport class HemisphereLight extends Light {\n static type = 'hemisphere-light'\n /** @internal @type {LightKind} */\n static kind = 'hemisphere'\n // 'color' is accepted too: the constructor passes 'sky' on as the base light colour\n static get OPTIONS() { return [...NODE_OPTIONS, 'sky', 'ground', 'intensity', 'color'] }\n\n #ground = new Color(0x444444)\n\n /** @param {NodeOptions & { sky?: ColorInput, ground?: ColorInput, intensity?: number }} [options] */\n constructor(options = {}) {\n const { sky, ground, ...rest } = options\n super(sky !== undefined ? { ...rest, color: sky } : rest)\n if (ground !== undefined) this.#ground.set(ground, 'HemisphereLight')\n }\n\n /** The colour from above (same as `color`). @returns {Color} */\n get sky() { return this.color }\n /** @param {ColorInput} v */\n set sky(v) { this.color.set(v, 'HemisphereLight') }\n /** The colour from below. @returns {Color} */\n get ground() { return this.#ground }\n /** @param {ColorInput} v */\n set ground(v) { this.#ground.set(v, 'HemisphereLight') }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n const { color, ...rest } = super.cloneOptions()\n return { ...rest, sky: color, ground: this.#ground.clone() }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n const { color, ...rest } = super.jsonOptions()\n return { ...rest, ...(color ? { sky: color } : {}), ...(this.#ground.getHex() !== 0x444444 ? { ground: this.#ground.getStyle() } : {}) }\n }\n}\n\n/**\n * @typedef {LightOptions & { direction?: Vec3Input, target?: Vec3Input }} AimedLightOptions\n * direction: the way the light travels; target: a point it shines towards, in the same space as\n * position. Give one or the other.\n */\n\n/** Shared by lights that point somewhere. */\nclass AimedLight extends Light {\n #direction = new Vec3(0, -1, 0)\n /** @type {Vec3 | null} */ #target = null\n\n /** The way the light travels, in the parent's space; ignored when `target` is set. Assigning copies, normalised. @returns {Vec3} */\n get direction() { return this.#direction }\n /** @param {Vec3Input} v */\n set direction(v) {\n const owner = this.constructor.name\n this.#direction.copy(v, owner)\n if (this.#direction.len() === 0) fail(owner, \"'direction' can't be [0, 0, 0]\")\n this.#direction.normalize()\n }\n /** A point to shine towards, in the same space as position; assigning copies, null goes back to direction. @returns {Vec3 | null} */\n get target() { return this.#target }\n /** @param {Vec3Input | null} v */\n set target(v) { this.#target = setPoint(this.#target, v, this.constructor.name) }\n\n /** @param {AimedLightOptions} [options] */\n constructor(options = {}) {\n super(options)\n const owner = this.constructor.name\n if (options.direction !== undefined && options.target !== undefined) {\n fail(owner, \"give 'direction' or 'target', not both\")\n }\n if (options.direction !== undefined) this.direction = options.direction\n if (options.target !== undefined) this.target = options.target\n }\n\n /**\n * Shine at a world position or node: the target moves there, or the direction turns to it. (A\n * light's own rotation doesn't aim it - its direction or target does.)\n * @param {Vec3Input | Node} target\n * @returns {this}\n */\n lookAt(target) {\n const at = inParentSpace(this, target)\n if (this.target) this.target.copy(at)\n else if (!at.equals(this.position, 1e-9)) this.direction.copy(at.sub(this.position).normalize())\n return this\n }\n\n /** The light's direction in world space, as of the last update. @returns {Vec3} */\n get worldDirection() {\n const local = this.target ? this.target.clone().sub(this.position) : this.direction.clone()\n const m = this.parent ? this.parent.worldMatrix : null\n if (m) {\n // directions transform without translation\n const [x, y, z] = local\n local.set(m[0] * x + m[4] * y + m[8] * z, m[1] * x + m[5] * y + m[9] * z, m[2] * x + m[6] * y + m[10] * z)\n }\n return local.normalize()\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), ...(this.target ? { target: this.target.toArray() } : { direction: this.direction.toArray() }) }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.target ? { target: this.target.toArray() } : { direction: this.direction.toArray() }) }\n }\n}\n\n/** Parallel light from far away, like the sun. Position only matters for its shadow. */\nexport class DirectionalLight extends AimedLight {\n static type = 'directional-light'\n /** @internal @type {LightKind} */\n static kind = 'directional'\n static get OPTIONS() { return [...LIGHT_OPTIONS, 'direction', 'target', 'castShadow', 'shadowBounds'] }\n\n castShadow = false\n /** @type {Box3 | null} */\n #shadowBounds = null\n\n /** @param {AimedLightOptions & { castShadow?: boolean, shadowBounds?: Box3Input | null }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.castShadow !== undefined) this.castShadow = !!options.castShadow\n if (options.shadowBounds !== undefined) this.#setShadowBounds(options.shadowBounds)\n }\n\n /**\n * The part of the world, in world units, that has shadows - or null (the default) to follow\n * whatever casts them. The shadow map is fitted to what casts every frame, so one caster flung far\n * off spreads its texels over everything and every shadow blurs; set the area where things happen\n * and its shadows stay sharp. Casters outside it still shadow it, from wherever they stand.\n * Assigning copies.\n * @returns {Box3 | null}\n */\n get shadowBounds() { return this.#shadowBounds }\n\n /** @param {Box3Input | null} v */\n set shadowBounds(v) { this.#setShadowBounds(v) }\n\n /** @param {Box3Input | null} v */\n #setShadowBounds(v) {\n if (v === null) {\n this.#shadowBounds = null\n return\n }\n const b = /** @type {any} */ (v)\n if (!b || typeof b !== 'object' || !b.min || !b.max) {\n fail(this.constructor.name, `'shadowBounds' is a box - { min: [x, y, z], max: [x, y, z] } or a Box3 - or null, got ${describe(v)}`)\n }\n const box = new Box3(Vec3.fromInput(b.min, this.constructor.name), Vec3.fromInput(b.max, this.constructor.name))\n if (box.isEmpty()) fail(this.constructor.name, `'shadowBounds' min must not be above max on any axis, got ${describe(v)}`)\n this.#shadowBounds = box\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), castShadow: this.castShadow, shadowBounds: this.#shadowBounds }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n const b = this.#shadowBounds\n return { ...super.jsonOptions(), ...(this.castShadow ? { castShadow: true } : {}),\n ...(b ? { shadowBounds: { min: Array.from(b.min), max: Array.from(b.max) } } : {}) }\n }\n}\n\n/** Light from a point in all directions, falling off with the square of the distance. */\nexport class PointLight extends Light {\n static type = 'point-light'\n /** @internal @type {LightKind} */\n static kind = 'point'\n static get OPTIONS() { return [...LIGHT_OPTIONS, 'range', 'castShadow'] }\n\n /** Distance where the light fades to nothing; 0 for unlimited. */\n range = 0\n /**\n * Cast shadows all round: one point light a scene can. Everything that casts blocks it, round\n * it too - a lantern's walls, a pumpkin's shell - so light leaves only through the openings; give\n * a bulb or flame drawn at the light castShadow: false.\n */\n castShadow = false\n\n /** @param {LightOptions & { range?: number, castShadow?: boolean }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.range !== undefined) this.range = rangeOf(this.constructor.name, options.range)\n if (options.castShadow !== undefined) this.castShadow = !!options.castShadow\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), range: this.range, castShadow: this.castShadow }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.range ? { range: this.range } : {}), ...(this.castShadow ? { castShadow: true } : {}) }\n }\n}\n\n/** A cone of light from a point. */\nexport class SpotLight extends AimedLight {\n static type = 'spot-light'\n /** @internal @type {LightKind} */\n static kind = 'spot'\n static get OPTIONS() { return [...LIGHT_OPTIONS, 'direction', 'target', 'range', 'angle', 'penumbra', 'castShadow'] }\n\n range = 0\n /** Cast shadows: up to four spot lights a scene can. Anything round the light itself - its own lamp - doesn't block it. */\n castShadow = false\n /** Half-angle of the cone in radians. */\n angle = Math.PI / 6\n /** Softness of the edge, 0 (hard) to 1. */\n penumbra = 0.1\n\n /** @param {AimedLightOptions & { range?: number, angle?: number, penumbra?: number, castShadow?: boolean }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.castShadow !== undefined) this.castShadow = !!options.castShadow\n if (options.range !== undefined) this.range = rangeOf('SpotLight', options.range)\n if (options.angle !== undefined) {\n this.angle = checkNumber('SpotLight', 'angle', options.angle)\n if (this.angle <= 0 || this.angle > Math.PI / 2) fail('SpotLight', `'angle' is the cone's half-angle in radians, above 0 and up to PI/2, got ${this.angle}`)\n }\n if (options.penumbra !== undefined) {\n this.penumbra = checkNumber('SpotLight', 'penumbra', options.penumbra)\n if (this.penumbra < 0 || this.penumbra > 1) fail('SpotLight', `'penumbra' must be 0-1, got ${this.penumbra}`)\n }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), range: this.range, angle: this.angle, penumbra: this.penumbra, castShadow: this.castShadow }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = super.jsonOptions()\n if (this.range) json.range = this.range\n if (this.angle !== Math.PI / 6) json.angle = this.angle\n if (this.penumbra !== 0.1) json.penumbra = this.penumbra\n if (this.castShadow) json.castShadow = true\n return json\n }\n}\n\n/** @param {string} owner @param {unknown} v */\nfunction rangeOf(owner, v) {\n const r = checkNumber(owner, 'range', v)\n if (r < 0) fail(owner, `'range' can't be negative (0 means unlimited), got ${r}`)\n return r\n}\n","// Shader programs, compiled on first use and cached by kind and feature defines. Compiling is the\n// most of a first frame, so it runs in parallel where the browser can (KHR_parallel_shader_compile):\n// programs are started without waiting, drawing skips the ones still compiling, and the renderer\n// draws again when they are done. Nothing waits on a status check until a program is used.\nimport { shaderSource } from './shaders.js'\n\n/** @import { ShaderKind } from './shaders.js' */\n\n/**\n * @typedef {object} Program\n * @property {WebGLProgram} program\n * @property {string} key\n * @property {(name: string, value: any) => void} set set a uniform by name (ignored if the shader doesn't use it)\n * @property {number} frame the frame its per-frame uniforms were last set for\n * @property {boolean} ready compiled, linked and its uniforms found\n */\n\n/**\n * @typedef {Program & { shaders: [WebGLShader, WebGLShader], sources: [string, string] }} Building\n */\n\nexport class Programs {\n /** @type {Map<string, Program>} */ #cache = new Map()\n /** Compiling off the main thread is possible. */\n #parallel\n /** Full-screen passes have no attributes, but still want a vertex array of their own. @type {WebGLVertexArrayObject | null} */\n #empty = null\n\n /** @param {WebGL2RenderingContext} gl */\n constructor(gl) {\n this.gl = gl\n this.#parallel = !!gl.getExtension('KHR_parallel_shader_compile')\n }\n\n get count() {\n return this.#cache.size\n }\n\n /** Programs started but not finished compiling. */\n get compiling() {\n let n = 0\n for (const p of this.#cache.values()) if (!p.ready && !this.isReady(p)) n++\n return n\n }\n\n /**\n * A program, started compiling on first ask. It may not be ready yet - check isReady() before\n * drawing with it, or use ready() to wait.\n * @param {ShaderKind | string} kind a drawable kind, or a pass's name when it brings its sources\n * @param {string[]} defines\n * @param {[string, string]} [sources] a pass's vertex and fragment shaders\n * @returns {Program}\n */\n get(kind, defines, sources) {\n const key = `${kind}|${defines.join(',')}`\n let p = this.#cache.get(key)\n if (!p) {\n p = this.#start(key, shaderSource(sources ?? /** @type {ShaderKind} */ (kind), defines))\n this.#cache.set(key, p)\n }\n return p\n }\n\n /**\n * A program, waiting for it to finish compiling if it hasn't - for passes and picking, which\n * need their programs now.\n * @param {ShaderKind | string} kind @param {string[]} defines @param {[string, string]} [sources]\n * @returns {Program}\n */\n ready(kind, defines, sources) {\n const p = this.get(kind, defines, sources)\n if (!p.ready) this.#finish(/** @type {Building} */ (p))\n return p\n }\n\n /**\n * Has it finished compiling? Asks without waiting, and finishes it (finding its uniforms) once\n * it has.\n * @param {Program} p\n * @returns {boolean}\n */\n isReady(p) {\n if (p.ready) return true\n if (this.#parallel && !this.gl.getProgramParameter(p.program, 0x91b1 /* COMPLETION_STATUS_KHR */)) return false\n this.#finish(/** @type {Building} */ (p))\n return true\n }\n\n /** Forget everything - after a lost context. */\n /** Forget every program - after a lost context, when they are already gone. */\n reset() {\n this.#cache.clear()\n this.#empty = null\n // a lost context drops its extensions: ask again, which turns it back on (or finds it gone)\n this.#parallel = !!this.gl.getExtension('KHR_parallel_shader_compile')\n }\n\n /**\n * Draw one triangle over the whole target with the program in use - a full-screen pass, its corners\n * made in the vertex shader from the vertex index. Depth, culling and blending are the pass's own.\n */\n drawFullscreen() {\n const gl = this.gl\n this.#empty ??= gl.createVertexArray()\n gl.bindVertexArray(this.#empty)\n gl.drawArrays(gl.TRIANGLES, 0, 3)\n }\n\n dispose() {\n for (const p of this.#cache.values()) this.gl.deleteProgram(p.program)\n this.#cache.clear()\n if (this.#empty) this.gl.deleteVertexArray(this.#empty)\n this.#empty = null\n }\n\n /**\n * Start compiling and linking, without asking how it went - that would wait for it.\n * @param {string} key @param {[string, string]} sources @returns {Program}\n */\n #start(key, sources) {\n const gl = this.gl\n const shader = (type, source) => {\n const s = /** @type {WebGLShader} */ (gl.createShader(type))\n gl.shaderSource(s, source)\n gl.compileShader(s)\n return s\n }\n const program = /** @type {WebGLProgram} */ (gl.createProgram())\n const vs = shader(gl.VERTEX_SHADER, sources[0])\n const fs = shader(gl.FRAGMENT_SHADER, sources[1])\n gl.attachShader(program, vs)\n gl.attachShader(program, fs)\n gl.linkProgram(program)\n /** @type {Building} */\n const p = { program, key, frame: -1, ready: false, set() {}, shaders: [vs, fs], sources }\n // without parallel compiling there is nothing to gain by waiting until it's used\n if (!this.#parallel) this.#finish(p)\n return p\n }\n\n /** Check how compiling went - throwing the log if it failed - and find the uniforms. @param {Building} p */\n #finish(p) {\n const gl = this.gl\n const { program, key, shaders, sources } = p\n if (!gl.getProgramParameter(program, gl.LINK_STATUS) && !gl.isContextLost()) {\n // the shader that failed says why, with its source numbered to match the log\n shaders.forEach((s, i) => {\n if (gl.getShaderParameter(s, gl.COMPILE_STATUS)) return\n throw new Error(`phoria2: ${i ? 'fragment' : 'vertex'} shader '${key}' failed to compile:\\n${gl.getShaderInfoLog(s)}\\n${numbered(sources[i])}`)\n })\n throw new Error(`phoria2: shader program '${key}' failed to link: ${gl.getProgramInfoLog(program)}`)\n }\n for (const s of shaders) gl.deleteShader(s)\n\n // every active uniform, with a setter for its type; arrays are set from flat typed arrays\n /** @type {Map<string, (value: any) => void>} */\n const setters = new Map()\n const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)\n let unit = 0\n for (let i = 0; i < n; i++) {\n const info = /** @type {WebGLActiveInfo} */ (gl.getActiveUniform(program, i))\n const name = info.name.replace(/\\[0\\]$/, '')\n const loc = gl.getUniformLocation(program, info.name)\n const sampler = info.type === gl.SAMPLER_2D || info.type === gl.SAMPLER_2D_SHADOW || info.type === gl.SAMPLER_CUBE_SHADOW\n setters.set(name, setterFor(gl, info.type, loc, sampler ? unit++ : 0))\n }\n p.set = (name, value) => setters.get(name)?.(value)\n p.ready = true\n }\n}\n\n/** @param {WebGL2RenderingContext} gl @param {number} type @param {WebGLUniformLocation | null} loc @param {number} unit */\nfunction setterFor(gl, type, loc, unit) {\n switch (type) {\n case gl.FLOAT: return (v) => typeof v === 'number' ? gl.uniform1f(loc, v) : gl.uniform1fv(loc, v)\n case gl.FLOAT_VEC2: return (v) => gl.uniform2fv(loc, v)\n case gl.FLOAT_VEC3: return (v) => gl.uniform3fv(loc, v)\n case gl.FLOAT_VEC4: return (v) => gl.uniform4fv(loc, v)\n case gl.INT:\n case gl.BOOL: return (v) => gl.uniform1i(loc, v)\n case gl.UNSIGNED_INT: return (v) => gl.uniform1ui(loc, v)\n case gl.FLOAT_MAT3: return (v) => gl.uniformMatrix3fv(loc, false, v)\n case gl.FLOAT_MAT4: return (v) => gl.uniformMatrix4fv(loc, false, v)\n case gl.SAMPLER_2D:\n case gl.SAMPLER_2D_SHADOW: return (texture) => {\n gl.activeTexture(gl.TEXTURE0 + unit)\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.uniform1i(loc, unit)\n }\n case gl.SAMPLER_CUBE_SHADOW: return (texture) => {\n gl.activeTexture(gl.TEXTURE0 + unit)\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture)\n gl.uniform1i(loc, unit)\n }\n default: return () => {}\n }\n}\n\n/** @param {string} source */\nconst numbered = (source) => source.split('\\n').map((line, i) => `${String(i + 1).padStart(4)} ${line}`).join('\\n')\n","// GPU copies of geometry, instance data and textures, created on first use and kept in step with the\n// CPU objects through their `version` counters. Everything is keyed by object in WeakMaps, so a\n// dropped geometry's entry goes with it; dispose() frees the GL objects straight away.\nimport { ATTRIBUTES } from './shaders.js'\nimport { isVideo } from '../material/Texture.js'\n\n/** @import { Geometry } from '../geometry/Geometry.js' */\n/** @import { Texture, DataImage } from '../material/Texture.js' */\n/** @import { Scene } from '../scene/Scene.js' */\n\n// uploads bind textures here, out of the way of the units programs sample from\nconst UPLOAD_UNIT = 15\n// past this many changed regions since the last upload, those in each cell of a GRID x GRID split of\n// the image go as one rectangle round them - nearby changes together, far ones still apart\nconst MOST_REGIONS = 16, GRID = 4\n\n/**\n * @typedef {object} MeshBuffers\n * @property {WebGLVertexArrayObject} vao\n * @property {WebGLBuffer[]} buffers\n * @property {number} count indices or vertices to draw\n * @property {number} indexType gl.UNSIGNED_SHORT / gl.UNSIGNED_INT, or 0 when not indexed\n * @property {Geometry} geometry the geometry they were made from - an instanced mesh can be given another\n * @property {number} version geometry version they were made from\n * @property {number} instanceVersion instance data version (instanced meshes)\n * @property {WebGLBuffer | null} [matrixBuffer] per-instance matrices, refilled when only they change\n * @property {WebGLBuffer | null} [colorBuffer] per-instance colours, likewise\n * @property {Record<string, WebGLBuffer>} [attributes] the geometry's buffers by attribute\n * @property {string} [layout] the data's shape when made; while it holds, changes refill in place\n */\n\n/**\n * The sizes of everything uploaded - equal layouts can reuse the same buffers.\n * @param {Geometry} g\n * @param {{ instanceMatrices: Float32Array, instanceColors: Float32Array | null } | null} instances\n * @param {boolean} withNormals\n */\nfunction layoutOf(g, instances, withNormals, withTangents) {\n return [g.positions.length, withNormals, g.uvs?.length, g.uvs2?.length, g.colors?.length, g.indices?.length,\n instances?.instanceMatrices.length, instances?.instanceColors?.length, withTangents].join()\n}\n\n/**\n * Per-vertex tangents along the UVs' u, with the way v runs in w (Lengyel's method): smooth where\n * the normals are. Without UVs, around the mesh's up axis.\n * @param {Geometry} g\n * @returns {Float32Array}\n */\nexport function tangentsOf(g) {\n const p = g.positions, n = g.normals, uv = g.uvs, count = p.length / 3\n const out = new Float32Array(count * 4)\n const t = new Float32Array(count * 3), b = new Float32Array(count * 3)\n if (uv) {\n const idx = g.indices, triangles = (idx ? idx.length : count) / 3\n for (let k = 0; k < triangles; k++) {\n const i0 = idx ? idx[k * 3] : k * 3, i1 = idx ? idx[k * 3 + 1] : k * 3 + 1, i2 = idx ? idx[k * 3 + 2] : k * 3 + 2\n const e1x = p[i1 * 3] - p[i0 * 3], e1y = p[i1 * 3 + 1] - p[i0 * 3 + 1], e1z = p[i1 * 3 + 2] - p[i0 * 3 + 2]\n const e2x = p[i2 * 3] - p[i0 * 3], e2y = p[i2 * 3 + 1] - p[i0 * 3 + 1], e2z = p[i2 * 3 + 2] - p[i0 * 3 + 2]\n const du1 = uv[i1 * 2] - uv[i0 * 2], dv1 = uv[i1 * 2 + 1] - uv[i0 * 2 + 1]\n const du2 = uv[i2 * 2] - uv[i0 * 2], dv2 = uv[i2 * 2 + 1] - uv[i0 * 2 + 1]\n const det = du1 * dv2 - du2 * dv1\n if (Math.abs(det) < 1e-12) continue\n const r = 1 / det\n const tx = (e1x * dv2 - e2x * dv1) * r, ty = (e1y * dv2 - e2y * dv1) * r, tz = (e1z * dv2 - e2z * dv1) * r\n const bx = (e2x * du1 - e1x * du2) * r, by = (e2y * du1 - e1y * du2) * r, bz = (e2z * du1 - e1z * du2) * r\n for (const i of [i0, i1, i2]) {\n t[i * 3] += tx; t[i * 3 + 1] += ty; t[i * 3 + 2] += tz\n b[i * 3] += bx; b[i * 3 + 1] += by; b[i * 3 + 2] += bz\n }\n }\n }\n for (let i = 0; i < count; i++) {\n const nx = n[i * 3], ny = n[i * 3 + 1], nz = n[i * 3 + 2]\n let tx = t[i * 3], ty = t[i * 3 + 1], tz = t[i * 3 + 2]\n // onto the surface, square to the normal\n const d = nx * tx + ny * ty + nz * tz\n tx -= nx * d; ty -= ny * d; tz -= nz * d\n let len = Math.hypot(tx, ty, tz)\n if (len < 1e-9) {\n // no UVs here: around the up axis, or the x axis for a surface facing up or down\n if (Math.abs(ny) < 0.999) { tx = nz; ty = 0; tz = -nx } else { tx = 1; ty = 0; tz = 0 }\n const e = nx * tx + ny * ty + nz * tz\n tx -= nx * e; ty -= ny * e; tz -= nz * e\n len = Math.hypot(tx, ty, tz) || 1\n }\n out[i * 4] = tx / len; out[i * 4 + 1] = ty / len; out[i * 4 + 2] = tz / len\n // which way v runs against n x t: mirrored UVs turn the other way\n const cx = ny * tz - nz * ty, cy = nz * tx - nx * tz, cz = nx * ty - ny * tx\n out[i * 4 + 3] = cx * b[i * 3] + cy * b[i * 3 + 1] + cz * b[i * 3 + 2] < 0 ? -1 : 1\n }\n return out\n}\n\nconst UV_MATRIX = new Float32Array(9)\n\n/**\n * A map's UV transform as a 3x3 (column-major): repeat, then rotation about its centre, then offset -\n * glTF's KHR_texture_transform order, turning the way three.js and glTF viewers do. Written into one\n * shared array, so set it as a uniform straight away.\n * @param {{ repeat: number[], offset: number[], rotation: number, center: number[] }} t\n * @returns {Float32Array}\n */\nexport function uvMatrix(t) {\n const c = Math.cos(t.rotation), s = Math.sin(t.rotation)\n const [sx, sy] = t.repeat, [cx, cy] = t.center\n const m = UV_MATRIX\n m[0] = c * sx; m[1] = -s * sx; m[2] = 0\n m[3] = s * sy; m[4] = c * sy; m[5] = 0\n m[6] = cx - c * cx - s * cy + t.offset[0]; m[7] = cy + s * cx - c * cy + t.offset[1]; m[8] = 1\n return m\n}\n\n// a quad as a triangle strip of [along, across] corners, shared by every Lines draw\nconst LINE_CORNERS = new Float32Array([0, -1, 0, 1, 1, -1, 1, 1])\n// a point drawn as a square: position, colour, size, opacity, angle and index, as [location, floats,\n// offset in floats]\nconst SPRITE_LAYOUT = [[ATTRIBUTES.position, 3, 0], [ATTRIBUTES.color, 3, 3], [ATTRIBUTES.pointSize, 1, 6],\n [ATTRIBUTES.pointOpacity, 1, 7], [ATTRIBUTES.pointAngle, 1, 8], [ATTRIBUTES.pointIndex, 1, 9]]\nconst SPRITE_STRIDE = 10\n\nexport class Resources {\n /** @type {WebGL2RenderingContext} */ gl\n // one cache per way of drawing, since one geometry can be drawn as triangles, points and lines\n /** @type {WeakMap<object, MeshBuffers>} */ #triangles = new WeakMap()\n /** @type {WeakMap<object, MeshBuffers>} */ #points = new WeakMap()\n /** @type {WeakMap<object, MeshBuffers>} */ #lines = new WeakMap()\n /** Points drawn as squares: an instance a point. @type {WeakMap<object, MeshBuffers & { capacity: number, sorted: boolean, data: Float32Array }>} */ #sprites = new WeakMap()\n /** The GPU copy of each texture: the version it holds, and the storage it was made with. @type {WeakMap<Texture, { texture: WebGLTexture, version: number, width: number, height: number, internal: number }>} */ #textures = new WeakMap()\n /** @type {WebGLTexture | null} */ #white = null\n /** @type {WebGLBuffer | null} */ #corners = null\n /** Counts for renderer.info. */\n counts = { geometries: 0, textures: 0 }\n /** The renderer drawing right now - what it touches is marked as used by it. @type {object | null} */\n owner = null\n // which renderers have drawn each geometry, instanced mesh and texture (a shared context frees\n // one only when no renderer still draws it)\n /** @type {WeakMap<object, Set<object>>} */ #usedBy = new WeakMap()\n\n /** @param {WebGL2RenderingContext} gl */\n constructor(gl) {\n this.gl = gl\n }\n\n /** @type {{ ext: any, max: number } | null | undefined} */\n #aniso\n\n /** The anisotropic filtering extension and its limit, or null where there is none. */\n #anisotropic() {\n if (this.#aniso !== undefined) return this.#aniso\n const ext = this.gl.getExtension('EXT_texture_filter_anisotropic')\n this.#aniso = ext ? { ext, max: this.gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT) || 1 } : null\n return this.#aniso\n }\n\n /**\n * Vertex array for a mesh or points: the geometry's attributes, plus per-instance matrices and\n * colours when `instances` is given. Instanced meshes get their own vertex array, keyed by the node.\n * @param {Geometry} geometry\n * @param {{ instanceMatrices: Float32Array, instanceColors: Float32Array | null, version: number } | null} instances\n * @param {boolean} withNormals\n * @param {boolean} [withTangents] add tangents, for brushed metal - kept once added\n * @returns {MeshBuffers}\n */\n mesh(geometry, instances, withNormals, withTangents = false) {\n const key = instances ?? geometry\n this.#mark(key)\n const cache = withNormals ? this.#triangles : this.#points\n let entry = cache.get(key)\n // instanced buffers are kept by the node, so check it still has the same geometry\n const same = entry?.geometry === geometry\n withTangents = withNormals && (withTangents || (same && !!entry?.attributes?.tangent))\n if (entry && same && entry.version === geometry.version && (!instances || entry.instanceVersion === instances.version) &&\n withTangents === !!entry.attributes?.tangent) return entry\n const layout = layoutOf(geometry, instances, withNormals, withTangents)\n if (entry && same && entry.layout === layout) {\n // the data changed but kept its shape (moving vertices, particles, instances): refill in place\n if (entry.version !== geometry.version) {\n const a = /** @type {Record<string, WebGLBuffer>} */ (entry.attributes)\n this.#refill(a.position, geometry.positions)\n if (withNormals) this.#refill(a.normal, geometry.normals)\n if (geometry.uvs) this.#refill(a.uv, geometry.uvs)\n if (geometry.uvs2) this.#refill(a.uv2, geometry.uvs2)\n if (geometry.colors) this.#refill(a.color, geometry.colors)\n if (withTangents) this.#refill(a.tangent, tangentsOf(geometry))\n if (geometry.indices) {\n // the element binding belongs to the vertex array, so bind that first\n this.gl.bindVertexArray(entry.vao)\n this.gl.bufferSubData(this.gl.ELEMENT_ARRAY_BUFFER, 0, geometry.indices)\n this.gl.bindVertexArray(null)\n }\n entry.version = geometry.version\n }\n if (instances && entry.instanceVersion !== instances.version) {\n this.#refill(entry.matrixBuffer, instances.instanceMatrices)\n if (instances.instanceColors) this.#refill(entry.colorBuffer, instances.instanceColors)\n entry.instanceVersion = instances.version\n }\n return entry\n }\n if (entry) {\n this.#free(entry)\n // given another geometry: the old one is no longer held here, and the new one is watched\n if (!same) {\n this.counts.geometries--\n this.#watch(geometry, key, cache)\n }\n } else this.#watch(geometry, key, cache)\n\n const gl = this.gl\n const vao = /** @type {WebGLVertexArrayObject} */ (gl.createVertexArray())\n gl.bindVertexArray(vao)\n /** @type {WebGLBuffer[]} */\n const buffers = []\n const attribute = (location, data, size, divisor = 0) => {\n const buffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW)\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl.FLOAT, false, 0, 0)\n if (divisor) gl.vertexAttribDivisor(location, divisor)\n buffers.push(buffer)\n return buffer\n }\n /** @type {Record<string, WebGLBuffer>} */\n const attributes = {}\n attributes.position = attribute(ATTRIBUTES.position, geometry.positions, 3)\n if (withNormals) attributes.normal = attribute(ATTRIBUTES.normal, geometry.normals, 3)\n if (geometry.uvs) attributes.uv = attribute(ATTRIBUTES.uv, geometry.uvs, 2)\n else gl.vertexAttrib2f(ATTRIBUTES.uv, 0, 0)\n if (geometry.uvs2) attributes.uv2 = attribute(ATTRIBUTES.uv2, geometry.uvs2, 2)\n if (geometry.colors) attributes.color = attribute(ATTRIBUTES.color, geometry.colors, 3)\n else gl.vertexAttrib3f(ATTRIBUTES.color, 1, 1, 1)\n if (withTangents) attributes.tangent = attribute(ATTRIBUTES.tangent, tangentsOf(geometry), 4)\n\n let matrixBuffer = null, colorBuffer = null\n if (instances) {\n matrixBuffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, matrixBuffer)\n gl.bufferData(gl.ARRAY_BUFFER, instances.instanceMatrices, gl.STATIC_DRAW)\n for (let i = 0; i < 4; i++) {\n const location = ATTRIBUTES.instanceMatrix + i\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, 4, gl.FLOAT, false, 64, i * 16)\n gl.vertexAttribDivisor(location, 1)\n }\n buffers.push(matrixBuffer)\n if (instances.instanceColors) colorBuffer = attribute(ATTRIBUTES.instanceColor, instances.instanceColors, 3, 1)\n else gl.vertexAttrib3f(ATTRIBUTES.instanceColor, 1, 1, 1)\n }\n\n let indexType = 0\n if (geometry.indices) {\n const buffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, geometry.indices, gl.STATIC_DRAW)\n buffers.push(buffer)\n indexType = geometry.indices instanceof Uint32Array ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT\n }\n gl.bindVertexArray(null)\n\n entry = { vao, buffers, count: geometry.elementCount, indexType, geometry, version: geometry.version,\n instanceVersion: instances?.version ?? 0, matrixBuffer, colorBuffer, attributes, layout }\n cache.set(key, entry)\n return entry\n }\n\n /**\n * Draw a mesh's triangles - instanced or not, indexed or not - with the program in use, as far as\n * its drawn count goes. Every pass that draws meshes draws them this way.\n * @param {Geometry} geometry @param {{ instanceMatrices: Float32Array, instanceColors: Float32Array | null, version: number, count: number } | null} instances\n * @param {boolean} [withTangents] for brushed metal\n * @returns {number} triangles drawn\n */\n drawTriangles(geometry, instances, withTangents = false) {\n const gl = this.gl\n const buffers = this.mesh(geometry, instances, true, withTangents)\n gl.bindVertexArray(buffers.vao)\n const elements = geometry.drawnCount - geometry.drawnCount % 3\n const count = instances ? instances.count : 1\n if (buffers.indexType) {\n if (instances) gl.drawElementsInstanced(gl.TRIANGLES, elements, buffers.indexType, 0, count)\n else gl.drawElements(gl.TRIANGLES, elements, buffers.indexType, 0)\n } else if (instances) gl.drawArraysInstanced(gl.TRIANGLES, 0, elements, count)\n else gl.drawArrays(gl.TRIANGLES, 0, elements)\n return elements / 3 * count\n }\n\n /** @param {WebGLBuffer | null | undefined} buffer @param {Float32Array} data */\n #refill(buffer, data) {\n const gl = this.gl\n gl.bindBuffer(gl.ARRAY_BUFFER, /** @type {WebGLBuffer} */ (buffer))\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, data)\n }\n\n /**\n * Vertex array for Lines: one instance per segment with its two endpoints (and colours) and where\n * it is along its chain, expanded to a screen-space quad - and arrowheads - in the vertex shader.\n * @param {Geometry} geometry\n * @returns {MeshBuffers}\n */\n lines(geometry) {\n this.#mark(geometry)\n let entry = this.#lines.get(geometry)\n if (entry && entry.version === geometry.version) return entry\n if (entry) this.#free(entry)\n else this.#watch(geometry, geometry, this.#lines)\n\n const gl = this.gl\n const p = geometry.positions, c = geometry.colors, idx = geometry.indices\n const segments = geometry.elementCount / 2\n const ends = new Float32Array(segments * 6)\n const colors = new Float32Array(segments * 6).fill(1)\n // chains: runs of segments each starting where the one before ended - a polyline. Dashes run\n // on along a chain, and arrowheads go at its ends\n const info = new Float32Array(segments * 3)\n for (let s = 0; s < segments; s++) {\n const i0 = idx ? idx[s * 2] : s * 2, i1 = idx ? idx[s * 2 + 1] : s * 2 + 1\n for (let k = 0; k < 3; k++) {\n ends[s * 6 + k] = p[i0 * 3 + k]\n ends[s * 6 + 3 + k] = p[i1 * 3 + k]\n if (c) {\n colors[s * 6 + k] = c[i0 * 3 + k]\n colors[s * 6 + 3 + k] = c[i1 * 3 + k]\n }\n }\n const o = s * 6, joined = s > 0 && ends[o - 3] === ends[o] && ends[o - 2] === ends[o + 1] && ends[o - 1] === ends[o + 2]\n if (joined) {\n info[s * 3] = info[s * 3 - 3] + Math.hypot(ends[o - 3] - ends[o - 6], ends[o - 2] - ends[o - 5], ends[o - 1] - ends[o - 4])\n info[s * 3 - 1] = 0\n } else info[s * 3 + 1] = 1\n info[s * 3 + 2] = 1\n }\n\n const vao = /** @type {WebGLVertexArrayObject} */ (gl.createVertexArray())\n gl.bindVertexArray(vao)\n /** @type {WebGLBuffer[]} */\n const buffers = []\n const interleavedPair = (data, first, second) => {\n const buffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW)\n for (const [location, offset] of [[first, 0], [second, 12]]) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, 3, gl.FLOAT, false, 24, offset)\n gl.vertexAttribDivisor(location, 1)\n }\n buffers.push(buffer)\n }\n interleavedPair(ends, ATTRIBUTES.segmentStart, ATTRIBUTES.segmentEnd)\n interleavedPair(colors, ATTRIBUTES.segmentColorStart, ATTRIBUTES.segmentColorEnd)\n const chains = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, chains)\n gl.bufferData(gl.ARRAY_BUFFER, info, gl.STATIC_DRAW)\n gl.enableVertexAttribArray(ATTRIBUTES.segmentInfo)\n gl.vertexAttribPointer(ATTRIBUTES.segmentInfo, 3, gl.FLOAT, false, 0, 0)\n gl.vertexAttribDivisor(ATTRIBUTES.segmentInfo, 1)\n buffers.push(chains)\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#cornerBuffer())\n gl.enableVertexAttribArray(ATTRIBUTES.corner)\n gl.vertexAttribPointer(ATTRIBUTES.corner, 2, gl.FLOAT, false, 0, 0)\n gl.bindVertexArray(null)\n\n entry = { vao, buffers, count: segments, indexType: 0, geometry, version: geometry.version, instanceVersion: 0 }\n this.#lines.set(geometry, entry)\n return entry\n }\n\n /**\n * The GL texture for a Texture - a 1x1 white placeholder until its image has loaded.\n * @param {Texture} texture\n * @returns {WebGLTexture}\n */\n texture(texture) {\n if (!texture.image) return this.#whiteTexture()\n this.#mark(texture)\n const gl = this.gl\n let entry = this.#textures.get(texture)\n if (entry && entry.version === texture.version) return entry.texture\n // a video with no frame yet: what it showed before, or white - and try again next frame\n if (isVideo(texture.image) && /** @type {HTMLVideoElement} */ (texture.image).readyState < 2) return entry?.texture ?? this.#whiteTexture()\n if (!entry) {\n entry = { texture: /** @type {WebGLTexture} */ (gl.createTexture()), version: -1, width: 0, height: 0, internal: 0 }\n this.#textures.set(texture, entry)\n this.counts.textures++\n texture.onDispose(() => this.#freeTexture(texture))\n }\n gl.activeTexture(gl.TEXTURE0 + UPLOAD_UNIT)\n gl.bindTexture(gl.TEXTURE_2D, entry.texture)\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY)\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false)\n const image = texture.image\n const data = 'data' in image ? /** @type {DataImage} */ (image) : null\n // raw pixels: bytes as usual, floats (HDR) as half floats, which filter everywhere; sRGB textures\n // are stored as sRGB so sampling returns linear values, filtered correctly\n const float = !!data && data.data instanceof Float32Array\n const internal = float ? gl.RGBA16F : texture.colorSpace === 'srgb' ? gl.SRGB8_ALPHA8 : gl.RGBA8\n const type = float ? gl.FLOAT : gl.UNSIGNED_BYTE\n const [width, height] = sizeOf(image)\n if (entry.version < 0 || entry.width !== width || entry.height !== height || entry.internal !== internal) {\n // new storage: the first upload, or the image changed size or kind\n if (data) gl.texImage2D(gl.TEXTURE_2D, 0, internal, width, height, 0, gl.RGBA, type, data.data)\n else gl.texImage2D(gl.TEXTURE_2D, 0, internal, gl.RGBA, type, /** @type {TexImageSource} */ (image))\n Object.assign(entry, { width, height, internal })\n } else {\n // the same storage, refilled: just the parts that changed, when the updates since said - a\n // canvas drawn on a little at a time - or the whole image (a video's next frame). A flipped\n // image's rows run the other way, so it goes whole\n let regions = texture.flipY ? null : texture.changedSince(entry.version)\n if (regions && regions.length > MOST_REGIONS) regions = byCell(regions, width, height)\n for (const r of regions ?? [{ x: 0, y: 0, width, height }]) {\n // inside the image: a region over its edge is cut there, one off it sends nothing\n const x = Math.max(0, r.x), y = Math.max(0, r.y)\n const w = Math.min(width, r.x + r.width) - x, h = Math.min(height, r.y + r.height) - y\n if (!(w > 0 && h > 0)) continue\n gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, x)\n gl.pixelStorei(gl.UNPACK_SKIP_ROWS, y)\n if (data) gl.pixelStorei(gl.UNPACK_ROW_LENGTH, width)\n gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, w, h, gl.RGBA, type, /** @type {any} */ (data ? data.data : image))\n }\n gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0)\n gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0)\n gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0)\n }\n const wrap = { repeat: gl.REPEAT, clamp: gl.CLAMP_TO_EDGE, mirror: gl.MIRRORED_REPEAT }[texture.wrap]\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap)\n const nearest = texture.filter === 'nearest'\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, nearest ? gl.NEAREST : gl.LINEAR)\n if (texture.mipmaps) {\n gl.generateMipmap(gl.TEXTURE_2D)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, nearest ? gl.NEAREST_MIPMAP_NEAREST : gl.LINEAR_MIPMAP_LINEAR)\n // sharp at glancing angles - as far as the GPU goes\n const aniso = this.#anisotropic()\n if (aniso && !nearest) gl.texParameterf(gl.TEXTURE_2D, aniso.ext.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, aniso.max))\n } else {\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, nearest ? gl.NEAREST : gl.LINEAR)\n }\n entry.version = texture.version\n return entry.texture\n }\n\n /**\n * A renderer is done with a scene: free the GPU copies of its geometry and textures that no\n * other renderer still draws.\n * @param {object} owner @param {Scene} scene\n */\n release(owner, scene) {\n /** @type {Set<object>} */\n const keys = new Set()\n const env = /** @type {any} */ (scene).environment, bg = /** @type {any} */ (scene).background\n if (env && typeof env === 'object') keys.add(env)\n if (bg && 'version' in bg) keys.add(bg)\n scene.traverse((n) => {\n const d = /** @type {any} */ (n)\n if (!d.isDrawable) return\n keys.add(d.geometry)\n if ('instanceMatrices' in d) keys.add(d)\n for (const [, t] of d.material.textures) keys.add(t)\n })\n for (const key of keys) {\n const users = this.#usedBy.get(key)\n if (!users?.delete(owner) || users.size) continue\n this.#usedBy.delete(key)\n for (const cache of [this.#triangles, this.#points, this.#lines, this.#sprites]) {\n const entry = cache.get(key)\n if (!entry) continue\n this.#free(entry)\n cache.delete(key)\n this.counts.geometries--\n }\n this.#freeTexture(/** @type {Texture} */ (key))\n }\n }\n\n /** @param {object} key */\n #mark(key) {\n if (!this.owner) return\n let users = this.#usedBy.get(key)\n if (!users) this.#usedBy.set(key, users = new Set())\n users.add(this.owner)\n }\n\n /**\n * Vertex array for points drawn as squares: one instance a point - its position, colour, size,\n * opacity, angle and index - over the corner strip lines use. Given a model-view matrix, the points\n * go back to front (furthest first) - re-sorted every call, as the camera may have moved; without\n * one, in their own order; with undefined, in whatever order they were last sent (picking, which\n * reads each point's index and doesn't mind).\n * @param {Geometry} geometry @param {ArrayLike<number> | null} [modelView]\n * @returns {MeshBuffers}\n */\n sprites(geometry, modelView) {\n this.#mark(geometry)\n const gl = this.gl\n let entry = this.#sprites.get(geometry)\n const sorting = !!modelView\n if (entry && entry.version === geometry.version && !sorting && (modelView === undefined || !entry.sorted)) return entry\n const n = geometry.drawnVertices, count = geometry.vertexCount\n if (!entry || entry.capacity < count) {\n if (entry) this.#free(entry)\n else this.#watch(geometry, geometry, this.#sprites)\n const vao = /** @type {WebGLVertexArrayObject} */ (gl.createVertexArray())\n gl.bindVertexArray(vao)\n const buffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, count * SPRITE_STRIDE * 4, gl.DYNAMIC_DRAW)\n for (const [location, size, offset] of SPRITE_LAYOUT) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl.FLOAT, false, SPRITE_STRIDE * 4, offset * 4)\n gl.vertexAttribDivisor(location, 1)\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#cornerBuffer())\n gl.enableVertexAttribArray(ATTRIBUTES.corner)\n gl.vertexAttribPointer(ATTRIBUTES.corner, 2, gl.FLOAT, false, 0, 0)\n gl.bindVertexArray(null)\n entry = { vao, buffers: [buffer], count: 0, indexType: 0, geometry, version: -1, instanceVersion: 0, capacity: count, sorted: false, data: new Float32Array(count * SPRITE_STRIDE) }\n this.#sprites.set(geometry, entry)\n }\n const order = sorting ? backToFront(geometry.positions, n, /** @type {ArrayLike<number>} */ (modelView)) : null\n const p = geometry.positions, c = geometry.colors, sizes = geometry.sizes, opacities = geometry.opacities, angles = geometry.angles\n const data = entry.data\n for (let j = 0; j < n; j++) {\n const i = order ? order[j] : j, o = j * SPRITE_STRIDE\n data[o] = p[i * 3]\n data[o + 1] = p[i * 3 + 1]\n data[o + 2] = p[i * 3 + 2]\n data[o + 3] = c ? c[i * 3] : 1\n data[o + 4] = c ? c[i * 3 + 1] : 1\n data[o + 5] = c ? c[i * 3 + 2] : 1\n data[o + 6] = sizes ? sizes[i] : 1\n data[o + 7] = opacities ? opacities[i] : 1\n data[o + 8] = angles ? angles[i] : 0\n data[o + 9] = i\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, entry.buffers[0])\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, data, 0, n * SPRITE_STRIDE)\n Object.assign(entry, { count: n, version: geometry.version, sorted: sorting })\n return entry\n }\n\n /** @param {Texture} texture */\n #freeTexture(texture) {\n const entry = this.#textures.get(texture)\n if (!entry) return\n this.gl.deleteTexture(entry.texture)\n this.#textures.delete(texture)\n this.counts.textures--\n }\n\n /** Forget everything - after a lost context, when every GL object is already gone. */\n reset() {\n this.#triangles = new WeakMap()\n this.#points = new WeakMap()\n this.#lines = new WeakMap()\n this.#sprites = new WeakMap()\n this.#textures = new WeakMap()\n this.#usedBy = new WeakMap()\n this.#white = null\n this.#corners = null\n // extensions go with a lost context; the next texture asks for this one again\n this.#aniso = undefined\n this.counts = { geometries: 0, textures: 0 }\n }\n\n // free GL objects for a geometry when it is disposed\n /** @param {Geometry} geometry @param {object} key @param {WeakMap<object, MeshBuffers>} cache */\n #watch(geometry, key, cache) {\n this.counts.geometries++\n geometry.onDispose(() => {\n const entry = cache.get(key)\n // gone, or the node has another geometry now\n if (!entry || entry.geometry !== geometry) return\n this.#free(entry)\n cache.delete(key)\n this.counts.geometries--\n })\n }\n\n /** @param {MeshBuffers} entry */\n #free(entry) {\n const gl = this.gl\n gl.deleteVertexArray(entry.vao)\n for (const b of entry.buffers) gl.deleteBuffer(b)\n }\n\n #whiteTexture() {\n if (this.#white) return this.#white\n const gl = this.gl\n this.#white = /** @type {WebGLTexture} */ (gl.createTexture())\n gl.activeTexture(gl.TEXTURE0 + UPLOAD_UNIT)\n gl.bindTexture(gl.TEXTURE_2D, this.#white)\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 255, 255]))\n return this.#white\n }\n\n #cornerBuffer() {\n if (this.#corners) return this.#corners\n const gl = this.gl\n this.#corners = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#corners)\n gl.bufferData(gl.ARRAY_BUFFER, LINE_CORNERS, gl.STATIC_DRAW)\n return this.#corners\n }\n}\n\n/**\n * An image's size in pixels - a video's frames, an <img>'s own pixels rather than its size on the page.\n * @param {any} image @returns {[number, number]}\n */\nfunction sizeOf(image) {\n if (isVideo(image)) return [image.videoWidth, image.videoHeight]\n if ('naturalWidth' in image) return [image.naturalWidth, image.naturalHeight]\n return [image.width, image.height]\n}\n\n/**\n * Many regions as a few: those whose middles fall in the same cell of a GRID x GRID split of the\n * image, as one rectangle round them.\n * @param {import('../material/Texture.js').TextureRegion[]} regions @param {number} width @param {number} height\n */\nfunction byCell(regions, width, height) {\n /** @type {Map<number, number[]>} x0, y0, x1, y1 round each cell's regions */\n const cells = new Map()\n for (const r of regions) {\n const cx = Math.min(GRID - 1, Math.max(0, Math.floor((r.x + r.width / 2) / width * GRID)))\n const cy = Math.min(GRID - 1, Math.max(0, Math.floor((r.y + r.height / 2) / height * GRID)))\n const key = cy * GRID + cx, box = cells.get(key)\n if (!box) cells.set(key, [r.x, r.y, r.x + r.width, r.y + r.height])\n else {\n box[0] = Math.min(box[0], r.x)\n box[1] = Math.min(box[1], r.y)\n box[2] = Math.max(box[2], r.x + r.width)\n box[3] = Math.max(box[3], r.y + r.height)\n }\n }\n return [...cells.values()].map(([x0, y0, x1, y1]) => ({ x: x0, y: y0, width: x1 - x0, height: y1 - y0 }))\n}\n\n/**\n * The first n points' order furthest from the camera first: by their depth in view, given the\n * model-view matrix.\n * @param {Float32Array} p @param {number} n @param {ArrayLike<number>} m\n * @returns {Uint32Array}\n */\nfunction backToFront(p, n, m) {\n const depth = new Float32Array(n), order = new Uint32Array(n)\n for (let i = 0; i < n; i++) {\n // view space z: more negative is further away\n depth[i] = m[2] * p[i * 3] + m[6] * p[i * 3 + 1] + m[10] * p[i * 3 + 2] + m[14]\n order[i] = i\n }\n return order.sort((a, b) => depth[a] - depth[b])\n}\n","// A WebGL 2 context and everything made on it - programs, buffers, textures, the extra passes -\n// used by one renderer (its canvas's own context) or by many (one context shared by views that\n// draw into it and copy the picture to their own canvas, so a dashboard of 30 tiles stays well\n// under the browser's limit of about 16 live contexts).\nimport { fail } from '../validate.js'\nimport { Programs } from './programs.js'\nimport { Resources } from './resources.js'\n\n/** @import { Passes } from './passes.js' */\n/** @import { Picker } from './picking.js' */\n/** @import { Bloom } from './bloom.js' */\n/** @import { Scene } from '../scene/Scene.js' */\n\n/** @typedef {{ onReady: (() => void) | null }} ContextUser */\n\n/** @type {GLContext | null} */\nlet shared = null\n\nexport class GLContext {\n /** @type {HTMLCanvasElement | OffscreenCanvas} */ canvas\n /** @type {WebGL2RenderingContext} */ gl\n programs\n resources\n /** HDR environments, panorama backgrounds and shadows - loaded the first time a frame has one. @type {Passes | null} */\n passes = null\n /** GPU picking - loaded the first time something is picked. @type {Picker | null} */\n picker = null\n /** Bloom - loaded the first time a renderer asks for it. @type {Bloom | null} */\n bloom = null\n lost = false\n /** Counts frames across every renderer, so programs know when their per-frame uniforms are stale. */\n frame = 0\n /** @type {Set<ContextUser>} */ users = new Set()\n /** Shared by several renderers, each copying its picture out. */\n isShared\n #passesLoading = false\n #watchingCompiles = false\n #pickerLoading = false\n #bloomLoading = false\n /** @type {() => void} */ #removeListeners\n\n /**\n * @param {HTMLCanvasElement | OffscreenCanvas} canvas\n * @param {{ antialias?: boolean, shared?: boolean }} [options]\n */\n constructor(canvas, { antialias = true, shared: isShared = false } = {}) {\n this.canvas = canvas\n this.isShared = isShared\n // a canvas let go of moments ago keeps its context, rather than losing it\n const before = released.get(canvas)\n if (before) {\n clearTimeout(before.timer)\n released.delete(canvas)\n }\n // a stencil buffer for section planes' caps\n const gl = canvas.getContext('webgl2', { antialias, alpha: true, premultipliedAlpha: true, stencil: true, powerPreference: 'high-performance' })\n if (!gl) fail('WebGLRenderer', 'WebGL 2 is not available in this browser or on this device')\n this.gl = /** @type {WebGL2RenderingContext} */ (gl)\n this.programs = new Programs(this.gl)\n this.resources = new Resources(this.gl)\n\n // a lost context (GPU reset, too many contexts) is restored by the browser; every GPU object\n // is then recreated from the CPU-side data, and every renderer drawn again\n const lost = (/** @type {Event} */ e) => {\n e.preventDefault()\n this.lost = true\n }\n const restored = () => {\n this.lost = false\n this.programs.reset()\n this.resources.reset()\n this.passes?.reset()\n this.picker?.reset()\n this.bloom?.reset()\n for (const user of this.users) user.onReady?.()\n }\n canvas.addEventListener('webglcontextlost', lost)\n canvas.addEventListener('webglcontextrestored', restored)\n this.#removeListeners = () => {\n canvas.removeEventListener('webglcontextlost', lost)\n canvas.removeEventListener('webglcontextrestored', restored)\n }\n // ...or, let go of long enough ago that it was lost, asks for it back: drawing waits until the\n // browser restores it, then goes ahead as after any lost context\n if (before && gl.isContextLost()) {\n this.lost = true\n before.lose?.restoreContext()\n }\n }\n\n /** The page's shared context, made on first use. @returns {GLContext} */\n static shared() {\n if (!shared) {\n const canvas = typeof document !== 'undefined' ? document.createElement('canvas') : new OffscreenCanvas(1, 1)\n shared = new GLContext(canvas, { shared: true })\n }\n return shared\n }\n\n /**\n * Make the drawing buffer at least this big (a shared context draws each view into its corner).\n * It only grows, so views of different sizes don't reallocate it every frame.\n * @param {number} width @param {number} height\n */\n fit(width, height) {\n const c = this.canvas\n if (c.width >= width && c.height >= height) return\n // round up, so a canvas growing a pixel at a time doesn't reallocate each time\n c.width = Math.max(c.width, Math.ceil(width / 256) * 256)\n c.height = Math.max(c.height, Math.ceil(height / 256) * 256)\n }\n\n /**\n * The extra passes, once loaded; the first call that needs them starts loading them, and every\n * renderer on this context is told when they arrive.\n * @param {boolean} needed\n * @returns {Passes | null}\n */\n loadPasses(needed) {\n if (this.passes || !needed || this.#passesLoading) return this.passes\n this.#passesLoading = true\n import('./passes.js').then(({ Passes }) => {\n this.passes = new Passes(this.gl, this.programs, this.resources)\n for (const user of this.users) user.onReady?.()\n })\n return null\n }\n\n /**\n * Programs are compiling in the background: tell every renderer on this context when they are\n * all done, so it draws again with them.\n */\n whenCompiled() {\n if (this.#watchingCompiles) return\n this.#watchingCompiles = true\n const check = () => {\n if (this.lost || !this.users.size) {\n this.#watchingCompiles = false\n return\n }\n if (this.programs.compiling) {\n setTimeout(check, 4)\n return\n }\n this.#watchingCompiles = false\n for (const user of this.users) user.onReady?.()\n }\n setTimeout(check, 4)\n }\n\n /**\n * GPU picking, once loaded; the first call starts loading it, and every renderer on this context\n * is told when it arrives.\n * @returns {Picker | null}\n */\n loadPicker() {\n if (this.picker || this.#pickerLoading) return this.picker\n this.#pickerLoading = true\n import('./picking.js').then(({ Picker }) => {\n this.picker = new Picker(this.gl, this.programs, this.resources)\n for (const user of this.users) user.onReady?.()\n })\n return null\n }\n\n /**\n * Bloom, once loaded; the first call starts loading it, and every renderer on this context is\n * told when it arrives.\n * @returns {Bloom | null}\n */\n loadBloom() {\n if (this.bloom || this.#bloomLoading) return this.bloom\n this.#bloomLoading = true\n import('./bloom.js').then(({ Bloom }) => {\n this.bloom = new Bloom(this.gl, this.programs)\n for (const user of this.users) user.onReady?.()\n })\n return null\n }\n\n /**\n * A renderer is done with this context. Its scene's GPU copies are freed unless another renderer\n * still draws them; the last user frees everything, losing the context on purpose so the\n * browser reclaims it. A canvas's own context is lost a moment later rather than at once: a new\n * renderer on the same canvas before then - React's StrictMode mounts, disposes and mounts again\n * in one go - keeps the live context, as a canvas only ever has the one.\n * @param {ContextUser} user\n * @param {Scene} [scene] what the renderer drew\n */\n release(user, scene) {\n this.users.delete(user)\n if (scene) this.resources.release(user, scene)\n if (this.users.size) return\n this.programs.dispose()\n this.resources.reset()\n this.passes?.reset()\n this.bloom?.dispose()\n this.#removeListeners()\n const lose = this.gl.getExtension('WEBGL_lose_context')\n if (this === shared) {\n lose?.loseContext()\n shared = null\n return\n }\n released.set(this.canvas, { lose, timer: setTimeout(() => lose?.loseContext()) })\n }\n}\n\n/**\n * Canvases whose last renderer let go of them, with the timer that will lose the context and the\n * extension that does it (kept, as a lost context gives out no extensions to restore it with).\n * @type {WeakMap<object, { lose: any, timer: ReturnType<typeof setTimeout> }>}\n */\nconst released = new WeakMap()\n","import * as mat3 from '../math/mat3.js'\nimport * as mat4 from '../math/mat4.js'\nimport { Geometry } from '../geometry/Geometry.js'\nimport { Material } from '../material/Material.js'\nimport { CLIP_ONLY_FRAGMENT, MESH_VERTEX } from './shaders.js'\nimport { collect } from '../frame.js'\nimport { checkNumber, checkOneOf, checkOptions, checkRange, describe, fail, warnOnce } from '../validate.js'\nimport { GLContext } from './context.js'\nimport { uvMatrix } from './resources.js'\n\n/** @import { FrameDescription, DrawItem, FrameLight, FrameCap } from '../frame.js' */\n/** @import { Scene } from '../scene/Scene.js' */\n/** @import { Camera } from '../scene/cameras.js' */\n/** @import { Texture } from '../material/Texture.js' */\n/** @import { Environment } from './passes.js' */\n/** @import { GPUHit } from './picking.js' */\n\n/** @typedef {'aces' | 'neutral' | 'none'} ToneMapping */\n\n/**\n * Glow round the bright parts of the picture - emissive materials, additive points and lines, lit\n * highlights - as light spills round them through a lens.\n * @typedef {object} BloomOptions\n * @property {number} [strength] how much glow is added (default 1)\n * @property {number} [radius] 0 - 1: how far it spreads (default 0.6)\n * @property {number} [threshold] 0 - 1: how bright a colour has to be to glow (default 0.6)\n */\n\n/**\n * @typedef {object} WebGLRendererOptions\n * @property {HTMLCanvasElement | OffscreenCanvas} canvas\n * @property {boolean} [shared] draw with the page's one shared WebGL context and copy the picture to\n * this canvas, instead of giving the canvas a context of its own - for pages with many views\n * (browsers allow about 16 live contexts). The View decides this; see its 'context' option.\n * @property {boolean} [antialias] multisampling (default true; a shared context always has it)\n * @property {boolean} [outlineAntialias] soft-edged outlines with round corners (default: as antialias)\n * @property {ToneMapping} [toneMapping] how lit colours are mapped to the screen: 'neutral' keeps colours\n * true (Khronos PBR Neutral, the default), 'aces' is filmic, 'none' clips\n * @property {number} [exposure] (default 1)\n * @property {number} [pixelRatio] drawing buffer pixels per CSS pixel (default 1; View sets it)\n * @property {boolean | BloomOptions} [bloom] glow round bright parts (default off); loads its code the first time\n */\n\nconst OPTIONS = ['canvas', 'shared', 'antialias', 'outlineAntialias', 'toneMapping', 'exposure', 'pixelRatio', 'bloom']\nconst BLOOM = { strength: 1, radius: 0.6, threshold: 0.6 }\n/** What bloom: { ... } takes, and hints for names people reach for instead. */\nexport const BLOOM_OPTIONS = Object.keys(BLOOM)\nexport const BLOOM_HINTS = { intensity: \"use 'strength'\", amount: \"use 'strength'\", size: \"use 'radius'\", blur: \"use 'radius'\" }\nconst HINTS = { alpha: 'the canvas is always transparent where the scene has no background' }\n\n/**\n * Bloom options as settings: true for the defaults, false or null for none.\n * @param {string} owner @param {boolean | BloomOptions | null | undefined} value\n * @returns {Required<BloomOptions> | null}\n */\nexport function bloomSettings(owner, value) {\n if (value === undefined || value === null || value === false) return null\n if (value === true) return { ...BLOOM }\n if (typeof value !== 'object') fail(owner, `bloom is true, false or { strength, radius, threshold }, got ${describe(value)}`)\n checkOptions(`${owner} bloom`, value, BLOOM_OPTIONS, BLOOM_HINTS)\n const settings = { ...BLOOM }\n for (const key of /** @type {(keyof BloomOptions)[]} */ (Object.keys(BLOOM))) {\n if (value[key] !== undefined) settings[key] = checkNumber(`${owner} bloom`, key, value[key])\n }\n return settings\n}\nconst TONE_MAPPING = { none: 0, aces: 1, neutral: 2 }\n// material maps and the shader feature each one switches on (all but emissive need lighting)\n/** @type {import('./passes.js').ShadowMap[]} */\nconst NO_SHADOWS = []\nconst MAP_DEFINES = { roughnessMap: 'ROUGHNESS_MAP', metalnessMap: 'METALNESS_MAP', normalMap: 'NORMAL_MAP', bumpMap: 'BUMP_MAP', aoMap: 'AO_MAP', lightMap: 'LIGHT_MAP' }\n// every map a mesh can sample - triplanar projection is only worth its varyings when there is one\nconst MAP_SLOTS = ['map', 'emissiveMap', ...Object.keys(MAP_DEFINES)]\nconst MAP_UNIFORMS = { matcap: 'uMatcap', map: 'uMap', roughnessMap: 'uRoughnessMap', metalnessMap: 'uMetalnessMap', normalMap: 'uNormalMap', bumpMap: 'uBumpMap', aoMap: 'uAoMap', emissiveMap: 'uEmissiveMap', lightMap: 'uLightMap' }\n// counting a cap's faces into the stencil: the solids' surfaces, colour and depth left alone\nconst CLIP_MASK = /** @type {[string, string]} */ ([MESH_VERTEX, CLIP_ONLY_FRAGMENT])\n// a cap: a square on the plane, two units across, facing +Y until it is placed\nconst CAP_SQUARE = new Geometry({\n positions: [-1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1], normals: [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0],\n uvs: [0, 0, 1, 0, 1, 1, 0, 1], indices: [0, 2, 1, 0, 3, 2],\n})\n// what a cap is drawn as - a plain node, never in a scene\nconst CAP_NODE = /** @type {any} */ ({ drawMode: 'triangles', receiveShadow: true, castShadow: false, renderOrder: 0 })\n\n/**\n * Draws a scene with WebGL 2. The View creates one; use it directly to drive your own loop:\n *\n * const renderer = new WebGLRenderer({ canvas })\n * renderer.setSize(canvas.clientWidth, canvas.clientHeight, devicePixelRatio)\n * scene.update(dt, t)\n * renderer.render(scene, camera)\n */\nexport class WebGLRenderer {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n /** The canvas the picture ends up on. @type {HTMLCanvasElement | OffscreenCanvas} */ canvas\n /** @type {ToneMapping} */ toneMapping = 'neutral'\n exposure = 1\n pixelRatio = 1\n /** Outlines with soft edges and round corners, or hard pixel steps; takes effect on the next frame. */\n outlineAntialias = true\n /** @type {Required<BloomOptions> | null} */ #bloom = null\n /** Counts from the last frame and the GPU caches. */\n info = { drawCalls: 0, triangles: 0, programs: 0, geometries: 0, textures: 0, compiling: 0 }\n /**\n * Called when something the last frame couldn't draw yet is ready - the code for HDR\n * environments, backgrounds and shadows, which loads the first time a scene has one. The View\n * redraws then. @type {(() => void) | null}\n */\n onReady = null\n\n /** The context drawn with: the canvas's own, or the page's shared one. @type {GLContext} */\n #gpu\n /** With a shared context: the canvas's 2D context, which the picture is copied into. @type {CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null} */\n #copy = null\n /** This frame's prefiltered environment, when it is an HDR image. @type {Environment | null} */ #environment = null\n /** This frame's shadows - directional, spot, point - for the meshes that receive them. @type {import('./passes.js').ShadowMap[]} */ #shadows = []\n /** @type {Float32Array} */ #normalMatrix = new Float32Array(9)\n /** Model-view for sorting points back to front. */\n #modelView = new Float32Array(16)\n /** @type {Record<string, any>} */ #lights = {}\n /** This frame waits for shaders to compile rather than leaving things out. */\n #wait = false\n /** This frame's light counts and environment, compiled into the lit programs. @type {string[]} */ #lightDefines = []\n #studio = false\n /** A cap's material, by colour, so each colour compiles and uploads once. @type {Map<number, Material>} */ #capMaterials = new Map()\n\n /** @param {WebGLRendererOptions} options */\n constructor(options) {\n checkOptions('WebGLRenderer', options, OPTIONS, HINTS)\n if (!options?.canvas) fail('WebGLRenderer', \"'canvas' is required\")\n this.canvas = options.canvas\n if (options.toneMapping !== undefined) this.toneMapping = checkOneOf('WebGLRenderer', 'toneMapping', options.toneMapping, ['aces', 'neutral', 'none'])\n if (options.exposure !== undefined) this.exposure = checkRange('WebGLRenderer', 'exposure', options.exposure, 0)\n if (options.pixelRatio !== undefined) this.pixelRatio = checkRange('WebGLRenderer', 'pixelRatio', options.pixelRatio, 0, Infinity, { above: true })\n this.#bloom = bloomSettings('WebGLRenderer', options.bloom)\n // outlines follow the picture's antialiasing unless told otherwise (a shared context always has it)\n this.outlineAntialias = options.outlineAntialias !== undefined ? !!options.outlineAntialias : options.shared || options.antialias !== false\n\n if (options.shared) {\n this.#gpu = GLContext.shared()\n const copy = this.canvas.getContext('2d')\n if (!copy) fail('WebGLRenderer', \"a shared renderer's canvas needs a 2D context - give it a canvas that has no WebGL context yet\")\n this.#copy = /** @type {CanvasRenderingContext2D} */ (copy)\n } else {\n this.#gpu = new GLContext(this.canvas, { antialias: options.antialias })\n }\n this.#gpu.users.add(this)\n }\n\n /**\n * Glow round the bright parts of the picture: null for none, or its settings. Set true, false or\n * { strength, radius, threshold }; change its numbers in place to tune it.\n * @returns {Required<BloomOptions> | null}\n */\n get bloom() {\n return this.#bloom\n }\n\n /** @param {boolean | BloomOptions | null} value */\n set bloom(value) {\n this.#bloom = bloomSettings('WebGLRenderer', value)\n }\n\n /** The WebGL 2 context drawn with - shared with other renderers when `shared` is set. @returns {WebGL2RenderingContext} */\n get gl() {\n return this.#gpu.gl\n }\n\n /** Drawing with the page's shared context? */\n get shared() {\n return this.#gpu.isShared\n }\n\n /**\n * Size the drawing buffer for a CSS size and pixel ratio. (The canvas's CSS size is left alone.)\n * @param {number} width CSS pixels\n * @param {number} height CSS pixels\n * @param {number} [pixelRatio]\n */\n setSize(width, height, pixelRatio = this.pixelRatio) {\n this.pixelRatio = pixelRatio\n this.canvas.width = Math.max(1, Math.round(width * pixelRatio))\n this.canvas.height = Math.max(1, Math.round(height * pixelRatio))\n }\n\n /**\n * Bring world matrices up to date, collect what's visible and draw it. Doesn't run update\n * handlers - the loop owner calls scene.update(dt, t) once per frame.\n * @param {Scene} scene\n * @param {Camera} camera\n * @returns {FrameDescription}\n */\n render(scene, camera) {\n scene.updateWorldTree()\n return this.renderFrame(collect(scene, camera))\n }\n\n /** @internal\n * Draw a frame. Shaders compile in the background where the browser allows, and what is still\n * compiling is left out (info.compiling counts it; onReady fires when it's done) - unless `wait`\n * is set, for a frame that must be complete, such as an image export.\n * @param {FrameDescription} frame\n * @param {{ wait?: boolean }} [options]\n * @returns {FrameDescription}\n */\n renderFrame(frame, { wait = false } = {}) {\n const gpu = this.#gpu\n if (gpu.lost) return frame\n const gl = gpu.gl\n gpu.frame++\n // what this frame touches counts as this renderer's, for freeing a shared context's copies\n gpu.resources.owner = this\n this.#wait = wait\n this.info.drawCalls = 0\n this.info.triangles = 0\n this.info.compiling = 0\n const width = this.canvas.width, height = this.canvas.height\n // a shared context draws into the bottom-left corner of its buffer, then copies that out\n if (gpu.isShared) gpu.fit(width, height)\n\n const env = frame.environment\n const bg = frame.background\n const passes = gpu.loadPasses(!!frame.shadow || frame.spotShadows.length > 0 || !!frame.pointShadow || frame.outlines.length > 0 || (typeof env === 'object' && !!env.image) || (!!bg && !('getHex' in bg) && !!bg.image))\n this.#environment = passes && typeof env === 'object' ? passes.environment(env) : null\n if (passes && typeof env === 'object' && env.image && !this.#environment) {\n warnOnce(env, env.isHDR ? \"this device can't render to float textures, which HDR environments need - lighting without it\"\n : \"'environment' needs an HDR image (a .hdr file) - lighting without it\")\n }\n // an HDR background is prefiltered here too, before the scene's target is bound: prefiltering\n // draws into targets of its own and leaves the framebuffer and viewport behind it\n if (passes && bg && !('getHex' in bg) && bg.isHDR) passes.environment(bg)\n // the lights' views first, each into its own depth texture\n this.#shadows = !passes ? [] : [\n frame.shadow && passes.shadowMap(frame.shadow),\n frame.spotShadows.length > 0 && passes.spotShadowMaps(frame.spotShadows),\n frame.pointShadow && passes.pointShadowMap(frame.pointShadow),\n ].filter((s) => !!s)\n // outlines' mask, drawn before the scene, so the scene's own target need not be left\n const outline = passes && frame.outlines.length ? passes.outlineMask(frame.outlines, frame, width, height, this.pixelRatio, this.outlineAntialias) : null\n\n // with bloom, the scene is drawn into a buffer of its own first (drawn plainly while its code loads)\n const bloom = this.#bloom ? gpu.loadBloom() : null\n // its buffers are big: once no view on this context wants bloom, they go (and come back if one does)\n if (!bloom && gpu.bloom && ![...gpu.users].some((u) => /** @type {any} */ (u).bloom)) gpu.bloom.dispose()\n if (bloom) bloom.begin(width, height)\n else {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null)\n gl.viewport(0, 0, width, height)\n }\n if (bg && 'getHex' in bg) {\n const [r, g, b] = bg.toSRGB()\n gl.clearColor(r, g, b, 1)\n } else {\n gl.clearColor(0, 0, 0, 0)\n }\n gl.depthMask(true)\n // clear only this view's corner of a shared buffer\n gl.enable(gl.SCISSOR_TEST)\n gl.scissor(0, 0, width, height)\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)\n gl.disable(gl.SCISSOR_TEST)\n if (passes && bg && !('getHex' in bg) && bg.image) {\n passes.background(frame, /** @type {Texture} */ (bg), { exposure: this.exposure, toneMapping: TONE_MAPPING[this.toneMapping] })\n }\n gl.enable(gl.DEPTH_TEST)\n gl.depthFunc(gl.LEQUAL)\n\n this.#gatherLights(frame)\n\n gl.disable(gl.BLEND)\n for (const item of frame.opaque) this.#draw(item, frame, false)\n // section planes' caps fill the cut faces of the solids just drawn, before anything see-through\n for (const cap of frame.caps) this.#cap(cap, frame, width, height)\n gl.enable(gl.BLEND)\n for (const item of frame.transparent) this.#draw(item, frame, true)\n // outlines over everything\n if (outline && passes) passes.outlineComposite(outline)\n gl.depthMask(true)\n gl.disable(gl.BLEND)\n gl.bindVertexArray(null)\n if (bloom && this.#bloom) bloom.end(this.#bloom)\n\n if (this.info.compiling) gpu.whenCompiled()\n if (this.#copy) {\n // the picture is the buffer's bottom-left corner; as an image, y runs down from the top\n const copy = this.#copy, source = gpu.canvas\n copy.globalCompositeOperation = 'copy'\n copy.drawImage(source, 0, source.height - height, width, height, 0, 0, width, height)\n }\n\n this.info.programs = gpu.programs.count\n this.info.geometries = gpu.resources.counts.geometries\n this.info.textures = gpu.resources.counts.textures\n return frame\n }\n\n /**\n * What is drawn at a pixel of a frame this renderer drew, found on the GPU: the drawable, which\n * instance, point or segment, and where. Undefined while the picking code loads (onReady fires\n * when it has) or while the context is lost - pick on the CPU meanwhile.\n * @param {FrameDescription} frame\n * @param {number} x @param {number} y CSS pixels from the canvas's top left\n * @returns {GPUHit | null | undefined}\n */\n pick(frame, x, y) {\n const gpu = this.#gpu\n if (gpu.lost) return undefined\n const picker = gpu.loadPicker()\n if (!picker) return undefined\n gpu.resources.owner = this\n const r = this.pixelRatio\n return picker.pick(frame, x * r, y * r, this.canvas.width, this.canvas.height, r)\n }\n\n /** @internal\n * pick() without waiting for the GPU: resolves once it has finished. Undefined while the picking\n * code loads; null while an earlier request is still out.\n * @param {FrameDescription} frame\n * @param {number} x @param {number} y CSS pixels from the canvas's top left\n * @returns {Promise<GPUHit | null> | null | undefined}\n */\n pickAsync(frame, x, y) {\n const gpu = this.#gpu\n if (gpu.lost) return undefined\n const picker = gpu.loadPicker()\n if (!picker) return undefined\n gpu.resources.owner = this\n const r = this.pixelRatio\n return picker.pickAsync(frame, x * r, y * r, this.canvas.width, this.canvas.height, r)\n }\n\n /**\n * Free the GPU resources this renderer made. With its own context that is everything (the\n * context is released); with the shared one, the copies of what `scene` draws that no other\n * renderer still uses - and everything, once the last renderer goes.\n * @param {Scene} [scene] what it drew\n */\n dispose(scene) {\n this.#gpu.release(this, scene)\n }\n\n /** @param {FrameDescription} frame */\n #gatherLights(frame) {\n const ambient = [0, 0, 0], sky = [0, 0, 0], ground = [0, 0, 0]\n // sized to the lights there are: the programs are compiled for exactly that many\n const directional = frame.lights.filter((l) => l.kind === 'directional').length\n const punctual = frame.lights.filter((l) => l.kind === 'point' || l.kind === 'spot').length\n const dirDirection = new Float32Array(directional * 3), dirColor = new Float32Array(directional * 3)\n const pos = new Float32Array(punctual * 3), color = new Float32Array(punctual * 3)\n const range = new Float32Array(punctual), direction = new Float32Array(punctual * 3), shadowTile = new Float32Array(punctual).fill(-1)\n const cone = new Float32Array(punctual * 2)\n let dirCount = 0, punctualCount = 0, pointShadowIndex = -1\n /** @param {number[] | Float32Array} out @param {number} offset @param {FrameLight} l @param {ArrayLike<number>} [c] */\n const addColor = (out, offset, l, c = l.color) => {\n out[offset] += c[0] * l.intensity\n out[offset + 1] += c[1] * l.intensity\n out[offset + 2] += c[2] * l.intensity\n }\n for (const l of frame.lights) {\n if (l.kind === 'ambient') addColor(ambient, 0, l)\n else if (l.kind === 'hemisphere') {\n addColor(sky, 0, l)\n addColor(ground, 0, l, l.ground)\n } else if (l.kind === 'directional') {\n const d = /** @type {ArrayLike<number>} */ (l.direction)\n // the shader wants the direction towards the light\n dirDirection.set([-d[0], -d[1], -d[2]], dirCount * 3)\n addColor(dirColor, dirCount * 3, l)\n dirCount++\n } else {\n const i = punctualCount++\n pos.set(/** @type {ArrayLike<number>} */ (l.position), i * 3)\n addColor(color, i * 3, l)\n range[i] = l.range ?? 0\n if (l === frame.pointShadow?.light) pointShadowIndex = i\n if (l.kind === 'spot') {\n direction.set(/** @type {ArrayLike<number>} */ (l.direction), i * 3)\n shadowTile[i] = l.shadowTile ?? -1\n const angle = /** @type {number} */ (l.angle)\n cone[i * 2] = Math.cos(angle)\n cone[i * 2 + 1] = Math.cos(angle * (1 - (l.penumbra ?? 0)))\n } else {\n // a cone wider than any angle: smoothstep(-2, -1, cos) is always 1\n cone[i * 2] = -2\n cone[i * 2 + 1] = -1\n }\n }\n }\n this.#lightDefines = [`NUM_DIRECTIONAL ${dirCount}`, `NUM_PUNCTUAL ${punctualCount}`]\n this.#studio = frame.environment === 'studio'\n this.#lights = {\n uAmbient: ambient, uHemisphereSky: sky, uHemisphereGround: ground,\n uDirectionalDirection: dirDirection, uDirectionalColor: dirColor,\n uPunctualPosition: pos, uPunctualColor: color, uPunctualRange: range,\n uPunctualDirection: direction, uPunctualCone: cone, uPunctualShadow: shadowTile, uPointShadowIndex: pointShadowIndex,\n }\n }\n\n /** @param {DrawItem} item @param {FrameDescription} frame @param {boolean} transparent */\n #draw(item, frame, transparent) {\n const gl = this.gl\n const { node, geometry, material, worldMatrix, instances } = item\n const mode = /** @type {any} */ (node).drawMode\n const kind = mode === 'points' ? 'points' : mode === 'lines' ? 'lines' : 'mesh'\n const receives = kind === 'mesh' && node.receiveShadow && !material.unlit\n const shadows = receives ? this.#shadows : NO_SHADOWS\n\n const clip = kind === 'mesh' ? item.clip : null\n const defines = this.#defines(kind, material, geometry.colors !== null, !!instances, geometry.uvs2 !== null)\n if (kind === 'points' && /** @type {any} */ (node).drawsSprites) defines.push('SPRITES')\n for (const shadow of shadows) defines.push(shadow.define)\n const fog = material.fog ? frame.fog : null\n if (fog) {\n defines.push('FOG')\n if (fog.linear) defines.push('FOG_LINEAR')\n if (material.blending === 'additive') defines.push('FOG_ADD')\n else if (material.blending === 'multiply') defines.push('FOG_MULTIPLY')\n }\n if (clip) defines.push('CLIP')\n const programs = this.#gpu.programs\n const program = programs.get(kind, defines)\n if (!programs.isReady(program)) {\n if (!this.#wait) {\n // still compiling: drawn once it's done, rather than holding up everything else\n this.info.compiling++\n return\n }\n programs.ready(kind, defines)\n }\n gl.useProgram(program.program)\n\n // per-frame values, once per program per frame\n if (program.frame !== this.#gpu.frame) {\n program.frame = this.#gpu.frame\n program.set('uView', frame.camera.view)\n program.set('uProjection', frame.camera.projection)\n program.set('uViewProjection', frame.camera.viewProjection)\n program.set('uCameraPosition', frame.camera.position)\n program.set('uExposure', this.exposure)\n program.set('uToneMapping', TONE_MAPPING[this.toneMapping])\n program.set('uResolution', [this.canvas.width, this.canvas.height])\n program.set('uNear', frame.camera.near)\n program.set('uScale', frame.camera.projection[5] * this.canvas.height / 2)\n if (kind === 'mesh' && !material.unlit) {\n for (const [name, value] of Object.entries(this.#lights)) program.set(name, value)\n const env = this.#environment\n if (env) {\n program.set('uEnvMaxLod', env.maxLod)\n program.set('uEnvSH', env.sh)\n program.set('uEnvIntensity', frame.environmentIntensity)\n }\n for (const shadow of shadows) for (const [name, value] of Object.entries(shadow.uniforms)) program.set(name, value)\n }\n }\n // the frame's own textures are bound every draw, not once a frame: other programs drawn in\n // between bind their maps to the same texture units, and a shadow sampler left reading an\n // ordinary texture makes the draw fail\n if (kind === 'mesh' && !material.unlit) {\n if (this.#environment) program.set('uEnvMap', this.#environment.prefiltered)\n for (const shadow of shadows) program.set(shadow.sampler, shadow.texture)\n }\n\n program.set('uModel', worldMatrix)\n const hl = frame.highlight\n if (hl && (hl.nodes ? hl.nodes.has(node) : hl.node === node)) {\n program.set('uHighlightIndex', hl.index ?? -1)\n program.set('uHighlight', [hl.color[0], hl.color[1], hl.color[2], hl.amount])\n } else {\n program.set('uHighlightIndex', -2)\n }\n program.set('uColor', material.color)\n program.set('uOpacity', material.opacity)\n if (fog) {\n program.set('uFogColor', fog.color)\n program.set('uFogRange', [fog.near, fog.far])\n program.set('uFogDensity', fog.density)\n }\n if (clip) program.set('uClipPlane', clip.plane)\n const e = material.emissive, k = material.emissiveIntensity\n program.set('uEmissive', [e[0] * k, e[1] * k, e[2] * k])\n program.set('uRoughness', material.roughness)\n program.set('uMetalness', material.metalness)\n program.set('uNormalScale', material.normalScale)\n if (material.bumpMap) program.set('uBumpScale', material.bumpScale)\n if (material.triplanar > 0) program.set('uTriplanar', material.triplanar)\n program.set('uAoMapIntensity', material.aoMapIntensity)\n if (material.transmission > 0) program.set('uTransmission', material.transmission)\n if (material.clearcoat > 0) {\n program.set('uClearcoat', material.clearcoat)\n program.set('uClearcoatRoughness', material.clearcoatRoughness)\n }\n // a non-metal's reflectance face on, from its ior and specular settings, and at grazing angles\n const ior = (material.ior - 1) / (material.ior + 1), sc = material.specularColor, si = material.specularIntensity\n program.set('uSpecular', [Math.min(ior * ior * sc[0], 1) * si, Math.min(ior * ior * sc[1], 1) * si, Math.min(ior * ior * sc[2], 1) * si, si])\n if (material.sheen > 0) {\n const c = material.sheenColor, k = material.sheen\n program.set('uSheenColor', [c[0] * k, c[1] * k, c[2] * k])\n program.set('uSheenRoughness', material.sheenRoughness)\n }\n if (material.anisotropy > 0) {\n program.set('uAnisotropy', material.anisotropy)\n program.set('uAnisotropyDirection', [Math.cos(material.anisotropyRotation), Math.sin(material.anisotropyRotation)])\n }\n if (material.translucency > 0) {\n const c = material.translucencyColor, k = material.translucency\n program.set('uTranslucency', [c[0] * k, c[1] * k, c[2] * k, k])\n }\n if (material.toon > 0) program.set('uToon', Math.max(2, Math.round(material.toon)))\n program.set('uAlphaTest', material.alphaTest)\n /** @type {[string, Texture][]} */\n const maps = kind === 'mesh' ? material.textures : material.map ? [['map', material.map]] : []\n // GL textures first (uploads use a unit of their own), then bind them to the samplers\n const bound = maps.map(([slot, texture]) => [MAP_UNIFORMS[slot], this.#gpu.resources.texture(texture)])\n for (const [name, texture] of bound) program.set(name, texture)\n // each map's own repeat, rotation and offset (a matcap takes no UVs)\n for (const [slot, texture] of maps) if (slot !== 'matcap') program.set(`${MAP_UNIFORMS[slot]}Uv`, uvMatrix(texture))\n if (material.lightMap) program.set('uLightMapIntensity', material.lightMapIntensity)\n program.set('uEnvStrength', material.environmentIntensity)\n\n // render state\n gl.depthMask(!transparent && material.depthWrite)\n if (material.depthTest) gl.enable(gl.DEPTH_TEST)\n else gl.disable(gl.DEPTH_TEST)\n if (transparent) {\n // output is premultiplied, so 'normal' is ONE / ONE_MINUS_SRC_ALPHA; 'multiply' scales what is\n // behind by the colour, as much as the opacity says: dst * (colour * opacity + 1 - opacity)\n if (material.blending === 'additive') gl.blendFunc(gl.ONE, gl.ONE)\n else if (material.blending === 'multiply') gl.blendFunc(gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA)\n else gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n }\n\n if (kind === 'lines') {\n gl.disable(gl.CULL_FACE)\n program.set('uWidth', material.width * this.pixelRatio)\n const arrows = /** @type {any} */ (node).arrowBits ?? 0\n program.set('uArrows', arrows)\n program.set('uArrowSize', /** @type {any} */ (node).arrowPixels?.(material.width) * this.pixelRatio || 0)\n if (material.dash > 0) {\n program.set('uDash', material.dash)\n program.set('uGap', material.gap || material.dash)\n program.set('uDashOffset', material.dashOffset)\n }\n const buffers = this.#gpu.resources.lines(geometry)\n gl.bindVertexArray(buffers.vao)\n // a quad a segment, and two arrowheads where there are any\n gl.drawArraysInstanced(gl.TRIANGLES, 0, arrows ? 12 : 6, Math.min(buffers.count, Math.floor(geometry.drawnCount / 2)))\n this.info.drawCalls++\n return\n }\n\n if (kind === 'points') {\n gl.disable(gl.CULL_FACE)\n program.set('uSize', material.sizeAttenuation ? material.size : material.size * this.pixelRatio)\n // round points are solid, but their edges are soft: blended over what is behind even in the\n // opaque pass, or the edge fades to black - a dark ring round every dot\n const round = !transparent && !material.map\n if (round) {\n gl.enable(gl.BLEND)\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n }\n if (/** @type {any} */ (node).drawsSprites) {\n // each point a square, any size and turned - drawn back to front when the points ask, for\n // smoke and other soft things that hide what is behind them\n program.set('uResolution', [this.canvas.width, this.canvas.height])\n const modelView = /** @type {any} */ (node).sort ? mat4.multiply(this.#modelView, frame.camera.view, worldMatrix) : null\n const buffers = this.#gpu.resources.sprites(geometry, modelView)\n gl.bindVertexArray(buffers.vao)\n gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, buffers.count)\n } else {\n const buffers = this.#gpu.resources.mesh(geometry, null, false)\n gl.bindVertexArray(buffers.vao)\n gl.drawArrays(gl.POINTS, 0, geometry.drawnVertices)\n }\n if (round) gl.disable(gl.BLEND)\n this.info.drawCalls++\n return\n }\n\n // triangles\n if (!mat3.normalFromMat4(this.#normalMatrix, worldMatrix)) mat3.identity(this.#normalMatrix)\n program.set('uNormalMatrix', this.#normalMatrix)\n // a mirroring transform (negative scale) reverses the winding - which also says which side is\n // the back, for double-sided materials\n gl.frontFace(mat4.determinant(worldMatrix) < 0 ? gl.CW : gl.CCW)\n if (material.doubleSided) {\n gl.disable(gl.CULL_FACE)\n } else {\n gl.enable(gl.CULL_FACE)\n gl.cullFace(gl.BACK)\n }\n // surfaces sit a hair behind their own depth, so a line lying on one - an edge, a seam, a\n // drawing's outline - shows whole rather than fighting it pixel by pixel\n gl.enable(gl.POLYGON_OFFSET_FILL)\n gl.polygonOffset(1, 2)\n this.info.triangles += this.#gpu.resources.drawTriangles(geometry, instances, material.anisotropy > 0 && !material.unlit)\n gl.disable(gl.POLYGON_OFFSET_FILL)\n this.info.drawCalls++\n }\n\n /**\n * Fill a section plane's cut through its solids. Each pixel's faces behind the plane are counted\n * into the stencil - in through a front face, out through a back one - so where the count isn't\n * zero, the plane there is inside a solid. A square on the plane, lit like any surface, is then\n * drawn over just those pixels: at the plane's own depth, so faces lying in it can't fight it.\n * @param {FrameCap} cap @param {FrameDescription} frame @param {number} width @param {number} height\n */\n #cap(cap, frame, width, height) {\n const gl = this.gl\n const programs = this.#gpu.programs\n // the counting program, for plain and instanced solids\n const masks = [false, true].map((instanced) => programs.get('clip-mask', instanced ? ['INSTANCED', 'CLIP'] : ['CLIP'], CLIP_MASK))\n if (!masks.every((p) => programs.isReady(p))) {\n if (!this.#wait) {\n this.info.compiling++\n return\n }\n for (const instanced of [false, true]) programs.ready('clip-mask', instanced ? ['INSTANCED', 'CLIP'] : ['CLIP'], CLIP_MASK)\n }\n gl.enable(gl.STENCIL_TEST)\n gl.enable(gl.SCISSOR_TEST)\n gl.scissor(0, 0, width, height)\n gl.clearStencil(0)\n gl.clear(gl.STENCIL_BUFFER_BIT)\n gl.disable(gl.SCISSOR_TEST)\n // count every face, hidden or not, without drawing a thing\n gl.colorMask(false, false, false, false)\n gl.depthMask(false)\n gl.disable(gl.DEPTH_TEST)\n gl.disable(gl.CULL_FACE)\n gl.stencilFunc(gl.ALWAYS, 0, 0xff)\n gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.INCR_WRAP)\n gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.DECR_WRAP)\n for (const item of cap.items) {\n const program = masks[item.instances ? 1 : 0]\n gl.useProgram(program.program)\n program.set('uViewProjection', frame.camera.viewProjection)\n program.set('uModel', item.worldMatrix)\n program.set('uClipPlane', cap.plane)\n gl.frontFace(mat4.determinant(item.worldMatrix) < 0 ? gl.CW : gl.CCW)\n this.#gpu.resources.drawTriangles(item.geometry, item.instances)\n this.info.drawCalls++\n }\n gl.colorMask(true, true, true, true)\n // then the plane, just where the count says\n gl.stencilFunc(gl.NOTEQUAL, 0, 0xff)\n gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP)\n this.#draw(this.#capItem(cap), frame, false)\n gl.disable(gl.STENCIL_TEST)\n }\n\n /** A cap's square, laid on its plane over the cut and facing out of it. @param {FrameCap} cap @returns {DrawItem} */\n #capItem(cap) {\n const hex = cap.color.getHex()\n let material = this.#capMaterials.get(hex)\n if (!material) this.#capMaterials.set(hex, material = new Material({ color: cap.color.getStyle(), roughness: 0.6 }))\n // axes for the square: y along the plane's normal, x and z across it\n const [nx, ny, nz] = cap.plane\n const across = Math.abs(nx) < 0.9 ? [1, 0, 0] : [0, 1, 0]\n let ax = ny * across[2] - nz * across[1], ay = nz * across[0] - nx * across[2], az = nx * across[1] - ny * across[0]\n const l = Math.hypot(ax, ay, az)\n ax /= l\n ay /= l\n az /= l\n // x cross y gives z, so the square keeps facing +y - out of the cut\n const bx = ay * nz - az * ny, by = az * nx - ax * nz, bz = ax * ny - ay * nx\n const s = cap.radius * 1.05, c = cap.center\n const worldMatrix = /** @type {any} */ (new Float32Array([ax * s, ay * s, az * s, 0, nx, ny, nz, 0, bx * s, by * s, bz * s, 0, c[0], c[1], c[2], 1]))\n return { node: CAP_NODE, geometry: CAP_SQUARE, material, worldMatrix, instances: null, depth: 0, clip: null }\n }\n\n /**\n * @param {'mesh' | 'points' | 'lines'} kind @param {Material} material\n * @param {boolean} hasColors @param {boolean} instanced @param {boolean} hasUvs2\n * @returns {string[]}\n */\n #defines(kind, material, hasColors, instanced, hasUvs2) {\n const d = []\n if (material.vertexColors && hasColors) d.push('VERTEX_COLORS')\n if (kind === 'mesh') {\n if (!material.unlit) {\n d.push('LIT')\n for (const [slot, define] of Object.entries(MAP_DEFINES)) if (material[slot]) d.push(define)\n d.push(...this.#lightDefines)\n if (this.#environment) d.push('ENV_MAP')\n else if (this.#studio) d.push('STUDIO')\n if (material.transmission > 0) d.push('TRANSMISSION')\n if (material.clearcoat > 0) d.push('CLEARCOAT')\n if (material.sheen > 0) d.push('SHEEN')\n if (material.anisotropy > 0) d.push('ANISOTROPY')\n if (material.translucency > 0) d.push('TRANSLUCENCY')\n if (material.matcap) d.push('MATCAP')\n if (material.toon > 0) d.push('TOON')\n }\n if (material.map) d.push('MAP')\n if (material.emissiveMap) d.push('EMISSIVE_MAP')\n if (material.alphaTest > 0) d.push('ALPHA_TEST')\n if (material.flatShading) d.push('FLAT_SHADING')\n if (material.doubleSided) d.push('DOUBLE_SIDED')\n if (material.triplanar > 0 && MAP_SLOTS.some((slot) => material[slot])) d.push('TRIPLANAR')\n // maps on the second UV set read it - where the geometry has one\n const second = hasUvs2 ? material.textures.filter(([slot, t]) => t.uvSet === 1 && slot !== 'matcap') : []\n if (second.length) d.push('UV2', ...second.map(([slot]) => `${MAP_UNIFORMS[slot]}Set vUv2`))\n if (instanced) d.push('INSTANCED')\n } else if (kind === 'points') {\n if (material.map) d.push('MAP')\n if (material.sizeAttenuation) d.push('SIZE_ATTENUATION')\n } else if (material.dash > 0) d.push('DASHED')\n // (points drawn as squares add SPRITES - see #draw, which knows the node)\n return d\n }\n}\n\n","import { collect, toScreen } from './frame.js'\nimport { LabelLayer } from './labels.js'\nimport { DRAG_START, OrbitControl } from './OrbitControl.js'\nimport { cameraPreset, fitPoints, framingScale, presetDirection } from './presets.js'\nimport { EASES } from './ease.js'\nimport { Raycaster } from './Raycaster.js'\nimport { pickArea } from './area.js'\nimport { ChangeWatch } from './watch.js'\nimport { Box3 } from './value/Box3.js'\nimport { Color } from './value/Color.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { Mat4 } from './value/Mat4.js'\nimport { Scene } from './scene/Scene.js'\nimport { Camera, PerspectiveCamera } from './scene/cameras.js'\nimport { DirectionalLight, HemisphereLight } from './scene/lights.js'\nimport { WebGLRenderer } from './webgl/WebGLRenderer.js'\nimport { checkOneOf, checkOptions, checkRange, describe, fail, warnOnce } from './validate.js'\n\n/** @import { OrbitOptions } from './OrbitControl.js' */\n/** @import { CameraPreset, FramingKeep } from './presets.js' */\n/** @import { Hit } from './Raycaster.js' */\n/** @import { FrameDescription, FrameHighlight } from './frame.js' */\n/** @import { Texture, TextureOptions } from './material/Texture.js' */\n/** @import { LabelStats } from './labels.js' */\n/** @import { ImageOptions } from './snapshot.js' */\n/** @import { Tooltip, TooltipContent } from './tooltip.js' */\n/** @import { ToneMapping, BloomOptions } from './webgl/WebGLRenderer.js' */\n/** @import { CameraOptions } from './scene/cameras.js' */\n/** @import { ColorInput, Vec3Input } from './types.js' */\n/** @import { Node } from './scene/Node.js' */\n/** @import { Keyboard, KeyboardOptions } from './keyboard.js' */\n\n/**\n * @typedef {'auto' | 'always' | 'manual'} RenderMode\n * auto: draw when something visible changed (checked cheaply each frame); always: every frame;\n * manual: only when view.render() or view.invalidate() is called.\n */\n\n/**\n * @typedef {object} ViewOptions\n * @property {HTMLCanvasElement | string} [canvas] element or CSS selector; default: a new canvas filling the window\n * @property {Scene} [scene] default: a new Scene (from a description: create({ type: 'scene', ... }))\n * @property {Camera | CameraPreset | (CameraOptions & { fov?: number })} [camera] a camera, a preset\n * ('perspective', 'isometric', 'top', 'front', 'side' - fitted to the scene on the first frame), or\n * PerspectiveCamera options. Default: 'perspective' - a three-quarter view from the front right\n * and above, fitted to the scene\n * @property {boolean | OrbitOptions} [orbit] mouse/touch camera control (default false)\n * @property {ColorInput | Texture | TextureOptions | null} [background] shortcut for scene.background: a colour or a panorama\n * @property {RenderMode} [renderMode] when to draw (default 'auto': only when something changed)\n * @property {FramingKeep | { keep?: FramingKeep, aspect?: number }} [framing] what stays in view when the canvas\n * changes shape: 'height' (default - the width varies), 'width', or 'both' (nothing framed is ever cut off); or\n * { keep, aspect }, where aspect is the width / height the camera was set up for (default: the canvas's shape\n * when the camera was set or framed)\n * @property {ColorInput | null} [highlight] tint whatever is under the pointer with this colour (default none)\n * @property {(hit: Hit) => TooltipContent} [tooltip] what to show for the thing under the pointer - see tooltip()\n * @property {number} [pixelRatio] default min(devicePixelRatio, 2)\n * @property {boolean} [antialias] (default true)\n * @property {boolean} [outlineAntialias] soft-edged outlines with round corners (default: as antialias); change it\n * any time with view.renderer.outlineAntialias\n * @property {'auto' | 'own' | 'shared'} [context] which WebGL context draws it: 'own' gives the canvas one of\n * its own; 'shared' draws with the page's one shared context and copies the picture over, so a page can hold\n * any number of views (browsers allow about 16 live contexts). 'auto' (default): own for the first four\n * views on a page, shared after that\n * @property {ToneMapping} [toneMapping] 'neutral' keeps colours true (default), 'aces' is filmic, 'none' clips\n * @property {number} [exposure] (default 1)\n * @property {boolean | BloomOptions} [bloom] glow round the bright parts of the picture - emissive materials,\n * additive points and lines (default off). true for the defaults, or { strength, radius, threshold }\n * @property {boolean} [autoLight] light a scene that has no lights, with one console note (default true)\n * @property {number} [maxDelta] longest frame step in seconds, so a background tab doesn't jump (default 0.1)\n * @property {'auto' | boolean} [reducedMotion] cut motion short, for people it makes unwell: frame() jumps rather\n * than glides, auto-rotation holds, and charts change at once with their flows still. Default 'auto': as the\n * system's setting (prefers-reduced-motion), followed as it changes\n * @property {boolean | KeyboardOptions} [keyboard] use without a pointer: the canvas joins the page's tab order, and\n * the arrow keys step through what can be hovered or clicked - each with the hover tint, the tooltip and hover\n * handlers - with Enter or Space to click and Escape to leave. A screen reader hears each one. { label: (hit) =>\n * text } says what it hears (default: the tooltip's text, the data, or the name). Default false\n * @property {string | null} [description] what the view shows, for screen readers: the canvas's label. With keyboard\n * on and no description, one is made from the scene (charts describe themselves)\n */\n\n/** @typedef {'click' | 'hover'} ViewEvent */\n/** @typedef {(hit: Hit | null, event: PointerEvent | MouseEvent | null) => void} ViewHandler */\n\nconst OPTIONS = ['canvas', 'scene', 'camera', 'orbit', 'background', 'renderMode', 'framing', 'highlight', 'tooltip', 'pixelRatio',\n 'antialias', 'outlineAntialias', 'context', 'toneMapping', 'exposure', 'bloom', 'autoLight', 'maxDelta', 'reducedMotion',\n 'keyboard', 'description']\nconst FRAMING_OPTIONS = ['keep', 'aspect']\nconst HINTS = {\n renderer: 'the View makes its renderer - read it from view.renderer',\n controls: \"use orbit: true (or orbit options); the control is then view.controls\",\n container: \"use canvas: an element or selector (a full-window canvas is made when omitted)\",\n onClick: \"use view.on('click', (hit) => ...)\",\n onHover: \"use view.on('hover', (hit) => ...)\",\n frameloop: \"use renderMode: 'auto' | 'always' | 'manual'\",\n keep: \"use framing: { keep: 'width' | 'height' | 'both' }\",\n fit: \"use framing: { keep: 'both' } to keep everything framed in view as the canvas changes shape\",\n aspect: \"the canvas sets the aspect; framing: { aspect } says which shape the camera was set up for\",\n}\nconst EVENT_HINTS = {\n mouseover: 'hover', mouseenter: 'hover', mousemove: 'hover', pointermove: 'hover', pointerover: 'hover', pointerenter: 'hover',\n mouseleave: 'hover', pointerleave: 'hover', tap: 'click', pick: 'click', select: 'click', pointerdown: 'click', mousedown: 'click',\n}\n// how far the highlight colour is mixed in\nconst HIGHLIGHT_AMOUNT = 0.45\n// what the keyboard's focus is tinted with when nothing says otherwise - focus must always show\nconst FOCUS_COLOR = Color.fromInput('#ffcc00')\n// views that get a WebGL context of their own before 'auto' starts sharing one\nconst OWN_CONTEXTS = 4\n// above this many things to test (instances, triangles, points, segments), picking goes to the\n// GPU; below it, rays on the CPU are quicker than a GPU round trip\nconst GPU_PICKING = 5000\nlet ownContexts = 0\n\n/**\n * The one object most apps touch: it owns the canvas, renderer, camera, controls, loop and pointer\n * interaction. It draws only when something changed, so an idle view costs almost nothing.\n *\n * const view = new View({ canvas: '#c', orbit: true })\n * const cube = view.scene.add(new Mesh({ geometry: box(2), material: { color: 'orange' } }))\n * view.on('click', (hit) => console.log(hit?.node))\n * view.start((dt) => cube.rotateY(0.6 * dt))\n */\nexport class View {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n /** What framing: { ... } takes. */\n static FRAMING_OPTIONS = FRAMING_OPTIONS\n /** @type {HTMLCanvasElement} */ canvas\n /** @type {Scene} */ scene\n /** @type {Camera} */ #camera\n /** @type {WebGLRenderer} */ renderer\n /** @type {OrbitControl | null} */ controls = null\n /** Seconds the loop has run. */\n time = 0\n /** Light the scene when it has none. */\n autoLight = true\n maxDelta = 0.1\n /** When to draw. @type {RenderMode} */\n renderMode = 'auto'\n /** @internal The last frame drawn. @type {FrameDescription | null} */\n lastFrame = null\n\n /** @type {((dt: number, t: number) => void) | null} */ #onFrame = null\n // time runs from the start, so update handlers (transitions, particles) work without start()\n #running = true\n #disposed = false\n #ownContext = false\n #ownCanvas = false\n #rafId = 0\n #lastTime = 0\n #dirty = true\n #onScreen = true\n #width = 0\n #height = 0\n #pixelRatio = 1\n #explicitPixelRatio = false\n #autoFrame = false\n // where a preset camera started, so fitting it on the first frame never undoes the app's own move\n /** @type {number[] | null} */ #autoFrameFrom = null\n // framing kept as the canvas changes shape: what to keep, the shape it was set for, and the\n // scale applied so far, so further changes stay relative (zooming by hand still works)\n /** @type {FramingKeep} */ #keep = 'height'\n #designed = 0\n #applied = 1\n #watch = new ChangeWatch()\n /** @type {(() => void)[]} */ #cleanup = []\n #labels\n /** @type {LabelStats | null} */ #labelStats = null\n // pointer interaction\n /** @type {{ click: Set<ViewHandler>, hover: Set<ViewHandler> }} */ #handlers = { click: new Set(), hover: new Set() }\n // the tooltip's code loads when first asked for, so apps without one don't carry it\n /** @type {Tooltip | null} */ #tooltip = null\n /** @type {((hit: Hit) => TooltipContent) | null} */ #tooltipContent = null\n #tooltipClass = ''\n #tooltipLoading = false\n /** @type {Color | null} */ #highlight = null\n /** @type {'auto' | boolean} */ #motion = 'auto'\n // keyboard use: its code loads when asked for; the thing it has stepped to shows as hovered\n /** @type {Keyboard | null} */ #keyboard = null\n /** @type {Hit | null} */ #keyFocus = null\n /** @type {string | null} */ #description = null\n // the canvas had no role, so describing it gave it one - taken away again with the description\n #gaveRole = false\n // the system's prefers-reduced-motion, kept up to date\n #systemReduced = false\n /** @type {{ x: number, y: number, clientX: number, clientY: number, event: PointerEvent } | null} */ #pointer = null\n #pickPending = false\n // a hover pick is out on the GPU\n #hoverBusy = false\n #dragging = false\n /**\n * A node being dragged: from the press, until the pointer lets go.\n * @type {{ drag: import('./scene/Node.js').Drag, id: number, x: number, y: number, press: import('./value/Ray.js').Ray, started: boolean } | null}\n */\n #drag = null\n /** The orbit's pointer handlers, once it has handed the pointer to the view. @type {ReturnType<OrbitControl['handOverPointer']> | null} */\n #orbitPointer = null\n /** The press in progress, and whether it has moved far enough to be a drag rather than a click. @type {{ id: number, x: number, y: number, moved: boolean } | null} */\n #press = null\n /** @type {Hit | null} */ #hovered = null\n /** The camera on its way to where frame() put it: from and to, and how far along. @type {Flight | null} */\n #flight = null\n /** A label the pointer is on, as a hit on what it labels - the canvas can't see the pointer there. @type {Hit | null} */\n #labelHover = null\n // used for scenes without lights; never added to the scene itself\n #autoSky = new HemisphereLight({ sky: '#ffffff', ground: '#444444', intensity: 0.5 })\n #autoSun = new DirectionalLight({ direction: [-0.5, -1, -0.6], intensity: 1.5 })\n #noted = false\n\n /** @param {ViewOptions} [options] */\n constructor(options = {}) {\n checkOptions('View', options, OPTIONS, HINTS)\n this.canvas = resolveCanvas(options.canvas)\n // one it made itself goes with it\n this.#ownCanvas = options.canvas === undefined\n\n if (options.scene === undefined) this.scene = new Scene()\n else if (options.scene instanceof Scene) this.scene = options.scene\n else fail('View', `'scene' must be a Scene${options.scene && typeof options.scene === 'object' && 'type' in options.scene ? \" - build one from a description with create({ type: 'scene', ... })\" : `, got ${describe(options.scene)}`}`)\n if (options.background !== undefined) this.scene.background = options.background\n\n if (options.camera instanceof Camera) {\n this.#camera = options.camera\n } else if (typeof options.camera === 'string') {\n this.#camera = cameraPreset(options.camera)\n this.#autoFrame = true\n } else if (options.camera === undefined) {\n // a three-quarter view, fitted to whatever the scene holds on its first frame\n this.#camera = cameraPreset('perspective')\n this.#autoFrame = true\n } else {\n this.#camera = new PerspectiveCamera({ position: [0, 1.5, 6], target: [0, 0, 0], ...options.camera })\n }\n if (this.#autoFrame) this.#autoFrameFrom = cameraPlace(this.#camera)\n\n const context = options.context === undefined ? 'auto' : checkOneOf('View', 'context', options.context, ['auto', 'own', 'shared'])\n // the renderer checks these too; checked here, the error names the View\n if (options.exposure !== undefined) checkRange('View', 'exposure', options.exposure, 0)\n const shared = context === 'shared' || (context === 'auto' && ownContexts >= OWN_CONTEXTS)\n this.renderer = new WebGLRenderer({ canvas: this.canvas, shared, antialias: options.antialias, outlineAntialias: options.outlineAntialias, toneMapping: options.toneMapping, exposure: options.exposure, bloom: options.bloom })\n if (!shared) {\n this.#ownContext = true\n ownContexts++\n }\n // shadows and HDR environments load their code on first use, then want another frame\n this.renderer.onReady = () => {\n // picking may have just arrived, so look under the pointer again\n this.#pickPending = true\n this.invalidate()\n }\n if (options.autoLight !== undefined) this.autoLight = !!options.autoLight\n if (options.reducedMotion !== undefined) this.#setMotion(options.reducedMotion)\n if (options.maxDelta !== undefined) this.maxDelta = checkRange('View', 'maxDelta', options.maxDelta, 0, Infinity, { above: true })\n if (options.renderMode !== undefined) this.renderMode = checkOneOf('View', 'renderMode', options.renderMode, ['auto', 'always', 'manual'])\n if (options.pixelRatio !== undefined) {\n this.#pixelRatio = checkRange('View', 'pixelRatio', options.pixelRatio, 0, Infinity, { above: true })\n this.#explicitPixelRatio = true\n }\n if (options.orbit !== undefined && options.orbit !== false && options.orbit !== true &&\n (typeof options.orbit !== 'object' || Array.isArray(options.orbit) || options.orbit === null)) {\n fail('View', `'orbit' must be true, false or orbit options such as { autoRotate: true }, got ${describe(options.orbit)}`)\n }\n if (options.orbit) {\n const orbit = options.orbit === true ? {} : options.orbit\n // a plan view pans like a map unless told otherwise\n const mode = orbit.mode ?? (options.camera === 'top' ? 'map' : undefined)\n this.controls = new OrbitControl(this.camera, this.canvas, mode ? { ...orbit, mode } : orbit)\n // the view owns the pointer and gives the orbit the presses that aren't drags of a node\n this.#orbitPointer = this.controls.handOverPointer()\n }\n if (options.highlight !== undefined) this.#setHighlight(options.highlight)\n if (options.tooltip !== undefined) this.tooltip(options.tooltip)\n if (options.description !== undefined) this.description = options.description\n if (options.keyboard !== undefined && options.keyboard !== false) this.#loadKeyboard(options.keyboard)\n this.#labels = new LabelLayer(this.canvas, {\n interactive: (label) => labelHandlers(label, 'click').length > 0 || labelHandlers(label, 'hover').length > 0,\n on: (type, label, e) => this.#labelPointer(type, label, e),\n })\n\n if (options.framing !== undefined) {\n // 'both' is short for { keep: 'both' }\n const f = typeof options.framing === 'string' ? { keep: options.framing } : options.framing\n checkOptions('View', f, FRAMING_OPTIONS, {}, 'framing')\n if (f.keep !== undefined) this.#keep = checkOneOf('View', 'framing.keep', f.keep, ['height', 'width', 'both'])\n if (f.aspect !== undefined) {\n if (!(f.aspect > 0)) fail('View', `framing.aspect is a width / height above 0, got ${describe(f.aspect)}`)\n this.#designed = f.aspect\n }\n }\n this.resize()\n this.#listen()\n this.#schedule()\n }\n\n /**\n * The camera drawn from. Set another camera, or a preset name to switch view - the orbit control\n * moves over, and a preset keeps looking at the same point, fitted to the scene.\n * @returns {Camera}\n */\n get camera() { return this.#camera }\n /** @param {Camera | CameraPreset} camera */\n set camera(camera) {\n if (typeof camera === 'string') {\n const old = /** @type {any} */ (this.#camera)\n const target = old.target ?? new Vec3()\n camera = cameraPreset(camera, { target, distance: Math.max(1e-3, old.position.distanceTo(target)) })\n this.#autoFrame = true\n } else {\n // a camera given explicitly stays where it was put, as one given to the constructor does\n this.#autoFrame = false\n }\n if (!(camera instanceof Camera)) fail('View', `'camera' must be a camera or a preset name, got ${describe(camera)}`)\n this.#flight = null\n this.#camera = camera\n if (this.#height) camera.aspect = this.#width / this.#height\n // a new camera is framed for the canvas as it is now\n this.#designed = camera.aspect\n this.#applied = 1\n if (this.controls) {\n // the control orbits the camera's target, so give it one where the old camera was looking\n camera.target ??= this.controls.target.clone()\n this.controls.camera = camera\n }\n if (this.#autoFrame) this.#autoFrameFrom = cameraPlace(camera)\n this.invalidate()\n }\n\n /**\n * Glow round the bright parts of the picture: null for none, or its settings. Set true, false or\n * { strength, radius, threshold }. (After changing its numbers in place, call invalidate().)\n * @returns {Required<BloomOptions> | null}\n */\n get bloom() { return this.renderer.bloom }\n /** @param {boolean | BloomOptions | null} v */\n set bloom(v) {\n this.renderer.bloom = v\n this.invalidate()\n }\n\n /** The colour mixed into whatever is under the pointer, or null for none. @returns {Color | null} */\n get highlight() { return this.#highlight }\n /** @param {ColorInput | null} v */\n set highlight(v) { this.#setHighlight(v) }\n\n /** @param {ColorInput | null} v */\n #setHighlight(v) {\n this.#highlight = v == null ? null : Color.fromInput(v, 'View')\n this.#pickPending = true\n this.invalidate()\n }\n\n /**\n * Is motion cut short - glides, auto-rotation, chart transitions? Set true or false, or 'auto' (the\n * default) to follow the system's setting. Read it for motion of your own, such as a timeline.\n * @returns {boolean}\n */\n get reducedMotion() { return this.#motion === 'auto' ? this.#systemReduced : this.#motion }\n /** @param {'auto' | boolean} v */\n set reducedMotion(v) { this.#setMotion(v) }\n\n /** @param {'auto' | boolean} v */\n #setMotion(v) {\n if (v !== 'auto' && typeof v !== 'boolean') fail('View', `'reducedMotion' is 'auto' (as the system's setting), true or false, got ${describe(v)}`)\n this.#motion = v\n this.invalidate()\n }\n\n /**\n * What the view shows, for screen readers - the canvas's label - or null. With keyboard on and no\n * description, one is made from the scene.\n * @returns {string | null}\n */\n get description() { return this.#description }\n /** @param {string | null} v */\n set description(v) {\n if (v !== null && typeof v !== 'string') fail('View', `'description' is text for screen readers, or null, got ${describe(v)}`)\n this.#description = v\n if (this.#keyboard) {\n this.#keyboard.setDescription(v)\n return\n }\n const canvas = this.canvas\n if (v === null) {\n canvas.removeAttribute('aria-label')\n if (this.#gaveRole) canvas.removeAttribute('role')\n this.#gaveRole = false\n return\n }\n canvas.setAttribute('aria-label', v)\n // a picture, to a screen reader, unless the page has said otherwise\n if (!canvas.hasAttribute('role')) {\n canvas.setAttribute('role', 'img')\n this.#gaveRole = true\n }\n }\n\n /** Canvas width in CSS pixels. */\n get width() { return this.#width }\n /** Canvas height in CSS pixels. */\n get height() { return this.#height }\n\n /** Resolves when every texture in the scene has loaded. @returns {Promise<void>} */\n get ready() {\n return this.scene.ready\n }\n\n /** The thing under the pointer, as of the last pointer move or redraw. @returns {Hit | null} */\n get hovered() {\n return this.#hovered\n }\n\n /** @internal\n * A layer over the canvas for HTML of your own - a title, a key, buttons. It tracks the canvas and\n * doesn't take pointer events itself; give children `pointer-events: auto` to make them clickable.\n * @returns {HTMLDivElement}\n */\n get overlay() {\n return this.#labels.root\n }\n\n /**\n * Call fn(dt, t) every frame (seconds), for app-level animation, and resume time if it was\n * stopped. Time - and the scene's update handlers - run from the start anyway; in 'auto' mode a\n * frame is still only drawn when something changed.\n * @param {(dt: number, t: number) => void} [fn]\n * @returns {this}\n */\n start(fn) {\n if (fn) this.#onFrame = fn\n if (!this.#running) {\n this.#running = true\n this.#lastTime = 0\n }\n this.#schedule()\n return this\n }\n\n /** Freeze time: the frame function and update handlers stop until start(). The view still redraws on changes. @returns {this} */\n stop() {\n this.#running = false\n return this\n }\n\n /** Is time running (not stopped)? */\n get running() {\n return this.#running\n }\n\n /**\n * Draw on the next frame even if nothing seems to have changed - after editing data the View\n * can't see, such as geometry arrays without needsUpdate(). Needed in 'manual' mode.\n * @returns {this}\n */\n invalidate() {\n this.#dirty = true\n this.#schedule()\n return this\n }\n\n /**\n * Advance exactly one frame by dt seconds and draw it. Deterministic - for tests, screenshots\n * and stepping a paused scene.\n * @param {number} dt\n * @returns {FrameDescription}\n */\n step(dt) {\n this.time += dt\n this.#onFrame?.(dt, this.time)\n // the same order as the live loop, so a stepped frame is the frame a user sees\n this.scene.motionReduced = this.reducedMotion\n this.scene.update(dt, this.time)\n this.#updateControls(dt)\n return this.#render(true)\n }\n\n /**\n * Move the camera by its control: auto-rotation and the glide after a drag. That isn't the app\n * moving the camera, so a camera still waiting to be fitted to the scene stays waiting.\n * @param {number} dt\n */\n #updateControls(dt) {\n if (this.#flight) return this.#fly(dt)\n if (!this.controls) return\n const waiting = this.#autoFrame && samePlace(cameraPlace(this.camera), this.#autoFrameFrom)\n this.controls.update(dt, this.reducedMotion)\n if (waiting) this.#autoFrameFrom = cameraPlace(this.camera)\n }\n\n /**\n * Draw the current state now, without advancing time. Shaders compile in the background on the\n * first frames, and what is still compiling appears a frame or two later.\n * @returns {FrameDescription}\n */\n render() {\n return this.#render(false)\n }\n\n /** @param {boolean} wait wait for shaders, for a complete frame (step, toImage) */\n #render(wait) {\n if (this.#autoFrame) {\n // fitted to the canvas as laid out now: a page still being built (a grid of tiles filling up)\n // can change its shape before the browser reports the resize, which comes after this frame\n this.resize()\n const bounds = this.scene.bounds\n // the app moved the camera itself: leave it where it put it\n if (!samePlace(cameraPlace(this.camera), this.#autoFrameFrom)) this.#autoFrame = false\n // what is drawn from the preset's direction, not every candidate label set\n else if (!bounds.isEmpty()) this.frame(this.scene)\n }\n this.scene.updateWorldTree()\n const frame = collect(this.scene, this.camera)\n if (this.autoLight && frame.lights.length === 0) this.#addAutoLights(frame)\n frame.highlight = this.#highlightFor(this.#hovered)\n this.#occlude(frame)\n this.renderer.renderFrame(frame, { wait })\n this.#labelStats = this.#labels.update(frame.labels, frame.overlays)\n // a node with its own tooltip needs the tooltip's code\n if (frame.tooltips && !this.#tooltip) this.#loadTooltip()\n this.lastFrame = frame\n this.#dirty = false\n // remember what was drawn - including what drawing changed, such as fitting the camera - so\n // the next frame compares against it and doesn't draw the same picture again\n if (this.renderMode === 'auto') this.#watch.changed(this.scene, this.camera)\n // things may have moved under a still pointer - or the keyboard's focus moved on screen\n if ((this.#pointer || this.#keyFocus) && this.#needsHover()) this.#pickPending = true\n return frame\n }\n\n /** Match the drawing buffer and camera to the canvas's displayed size. Automatic; call after manual changes. */\n resize() {\n const cw = this.canvas.clientWidth, ch = this.canvas.clientHeight\n // hidden (display: none, a closed tab): keep the size it had, and pick up where it was when shown\n if ((!cw || !ch) && this.#width) return\n // a canvas sized only by its width and height attributes grows with every buffer it is given - at a\n // pixel ratio of 2, without end. Seen growing to exactly the buffer just set, it is held at its size\n if (this.#width && this.#pixelRatio !== 1 && cw === Math.round(this.#width * this.#pixelRatio) && ch === Math.round(this.#height * this.#pixelRatio)) {\n this.canvas.style.width = `${this.#width}px`\n this.canvas.style.height = `${this.#height}px`\n return\n }\n const w = cw || this.canvas.width || 1\n const h = ch || this.canvas.height || 1\n if (!this.#explicitPixelRatio) this.#pixelRatio = Math.min(globalThis.devicePixelRatio || 1, 2)\n this.#width = w\n this.#height = h\n this.renderer.setSize(w, h, this.#pixelRatio)\n this.camera.aspect = w / h\n // keeping the framing can move the camera; that isn't the app placing it, so a camera still\n // waiting to be fitted to the scene stays waiting\n const waiting = this.#autoFrame && samePlace(cameraPlace(this.camera), this.#autoFrameFrom)\n this.#keepFraming()\n if (waiting) this.#autoFrameFrom = cameraPlace(this.camera)\n this.#dirty = true\n }\n\n /**\n * Move the camera so a node, a box or (with no argument) the whole scene fills the view. The orbit\n * target moves to its centre. It keeps the viewing direction unless given one - a preset's name\n * ('perspective', 'top', 'front'...) or a vector from the target towards the camera - and with a\n * duration it glides there, as a tour or a Reset button wants.\n *\n * view.frame(rack, { duration: 0.8 }) // fly to the rack\n * view.frame(undefined, { direction: 'perspective', duration: 0.6 }) // back to the start\n * @param {Node | Box3} [target] (default the scene)\n * @param {{ padding?: number, direction?: CameraPreset | Vec3Input, duration?: number }} [options] padding is\n * the margin around it, as a fraction of its size: 0 is a tight fit, 0.2 (the default) leaves a fifth.\n * duration is in seconds (default 0: straight there); a press or the wheel stops the glide, and with\n * reducedMotion it goes straight there\n * @returns {this}\n */\n frame(target = this.scene, { padding = 0.2, direction: towards, duration = 0 } = {}) {\n checkRange('View', 'frame() duration', duration, 0)\n const cam = /** @type {any} */ (this.camera)\n const from = placeOf(cam)\n this.#flight = null\n const fit = this.#fit('frame', target, padding, towards)\n // an explicit frame replaces the preset camera's fit on the first frame\n this.#autoFrame = false\n if (!fit) return this\n setPlace(cam, fit.place)\n cam.near = fit.near ?? cam.near\n cam.far = Math.max(cam.far, fit.far)\n // framed for the canvas as it is now\n this.#designed = cam.aspect\n this.#applied = 1\n if (duration > 0 && !this.reducedMotion) {\n // the camera starts where it was and glides there, frame by frame\n this.#flight = { from, to: placeOf(cam), time: 0, duration }\n setPlace(cam, from)\n }\n this.invalidate()\n return this\n }\n\n /**\n * Where frame() would put the camera, without moving it: its position, target and - for an\n * orthographic camera - height, or null when there is nothing to frame. For a camera of your own\n * that eases after something moving rather than jumping each frame:\n *\n * const aim = view.framing(debris)\n * if (aim) {\n * view.camera.position.lerp(aim.position, 0.1)\n * view.camera.target.lerp(aim.target, 0.1)\n * }\n * @param {Node | Box3} [target] (default the scene)\n * @param {{ padding?: number, direction?: CameraPreset | Vec3Input }} [options] as frame()\n * @returns {{ position: Vec3, target: Vec3, height?: number } | null}\n */\n framing(target = this.scene, { padding = 0.2, direction } = {}) {\n const fit = this.#fit('framing', target, padding, direction)\n if (!fit) return null\n const { position, target: at, height } = fit.place\n return height === undefined ? { position, target: at } : { position, target: at, height }\n }\n\n /**\n * The camera's place to frame something, worked out without moving it - for frame() and framing().\n * @param {string} method its caller, for errors @param {Node | Box3} target @param {number} padding\n * @param {CameraPreset | Vec3Input | undefined} towards\n * @returns {{ place: Place, near: number | undefined, far: number } | null}\n */\n #fit(method, target, padding, towards) {\n if (!(padding >= 0)) fail('View', `${method}() padding is the margin around, as a fraction of the size (0.2 = 20%), got ${describe(padding)}`)\n if (padding >= 1) warnOnce(this, `${method}() padding ${padding} leaves a margin of ${Math.round(padding * 100)}% - it is a fraction of the size (0.2 = 20%)`)\n const cam = /** @type {any} */ (this.camera)\n const direction = towards === undefined ? cam.position.clone().sub(cam.target ?? new Vec3()).normalize()\n : typeof towards === 'string' ? presetDirection(/** @type {CameraPreset} */ (towards)) : Vec3.fromInput(towards, 'View').normalize()\n if (towards !== undefined && !(direction.len() > 0)) fail('View', `${method}() direction is a preset name or a vector from the target towards the camera, got ${describe(towards)}`)\n if (direction.len() === 0) direction.set(0, 0.3, 1).normalize()\n const points = target instanceof Box3 ? corners(target) : this.#drawnPoints(target, direction)\n if (!points.length) return null\n const ortho = cam.constructor.type === 'orthographic-camera'\n const { center, size } = fitPoints(points, direction, { aspect: cam.aspect, fov: ortho ? undefined : cam.fov, padding })\n const radius = Math.max(1e-3, ...points.map((p) => Math.hypot(p[0] - center[0], p[1] - center[1], p[2] - center[2])))\n if (ortho) {\n return { place: { position: center.clone().add(direction.clone().multiplyScalar(radius * 4)), target: center, height: size },\n near: undefined, far: radius * 10 }\n }\n // keep the near/far range sensible for the model's size\n const distance = size\n return { place: { position: center.clone().add(direction.clone().multiplyScalar(distance)), target: center },\n near: Math.max(1e-3, distance / 1000), far: distance * 10 }\n }\n\n /**\n * One frame of a glide: round the target as it moves, closing the distance evenly, so the picture\n * turns and zooms rather than cutting through what is in view.\n * @param {number} dt\n */\n #fly(dt) {\n const f = /** @type {Flight} */ (this.#flight)\n f.time = Math.min(f.duration, f.time + dt)\n const e = EASES.inOut(f.time / f.duration)\n const cam = /** @type {any} */ (this.camera)\n const target = f.from.target.clone().lerp(f.to.target, e)\n const d0 = f.from.position.clone().sub(f.from.target), d1 = f.to.position.clone().sub(f.to.target)\n const r0 = d0.len() || 1e-6, r1 = d1.len() || 1e-6\n const way = turnBetween(d0.multiplyScalar(1 / r0), d1.multiplyScalar(1 / r1), e)\n setTarget(cam, target)\n cam.position.copy(target).add(way.multiplyScalar(r0 * (r1 / r0) ** e))\n if (f.to.height !== undefined) cam.height = f.from.height * (f.to.height / f.from.height) ** e\n if (f.time >= f.duration) {\n setPlace(cam, f.to)\n this.#flight = null\n }\n this.invalidate()\n }\n\n /**\n * The corners of each thing a node draws seen from along a direction - leaving out what a camera\n * there wouldn't show (hidden nodes, showFrom sets turned away), measured from where framing will\n * put the camera. All its bounds' corners when that leaves nothing.\n * @param {Node} node @param {Vec3} direction from the node towards the camera\n * @returns {number[][]}\n */\n #drawnPoints(node, direction) {\n const all = node.bounds\n if (all.isEmpty()) return []\n const cam = this.camera, at = cam.position.clone()\n cam.position.copy(all.getCenter()).add(direction.clone().multiplyScalar(Math.max(all.getRadius(), 1e-3) * 3))\n cam.updateWorld()\n const points = drawnPoints(node, cam)\n cam.position.copy(at)\n cam.updateWorld()\n return points.length ? points : corners(all)\n }\n\n /**\n * The nearest hit under a canvas position - CSS pixels from the canvas's top left, or a pointer\n * event. Found on the GPU from the last frame drawn (one pass, however many instances), then made\n * exact on the CPU; on the CPU alone until the picking code has loaded.\n * @param {number | MouseEvent} x\n * @param {number} [y]\n * @returns {Hit | null}\n */\n pick(x, y) {\n if (typeof x === 'object') {\n const rect = this.canvas.getBoundingClientRect()\n y = x.clientY - rect.top\n x = x.clientX - rect.left\n }\n const frame = this.#gpuFrame()\n const found = frame ? this.renderer.pick(frame, x, /** @type {number} */ (y)) : undefined\n if (found === undefined) return this.pickAll(x, y)[0] ?? null\n return found && this.#exact(found, frame)\n }\n\n /**\n * The ray from the camera through a canvas position - CSS pixels from its top left, or a pointer\n * event - in world space: for finding where the pointer is on a floor or any plane.\n *\n * const ray = view.rayAt(event)\n * const t = ray.intersectPlane([0, 1, 0], [0, 0, 0])\n * if (t !== null) chair.position.copy(ray.at(t))\n * @param {number | MouseEvent} x\n * @param {number} [y]\n * @returns {import('./value/Ray.js').Ray}\n */\n rayAt(x, y) {\n if (typeof x === 'object') {\n const rect = this.canvas.getBoundingClientRect()\n y = x.clientY - rect.top\n x = x.clientX - rect.left\n }\n const ndc = [(x / (this.#width || 1)) * 2 - 1, 1 - (/** @type {number} */ (y) / (this.#height || 1)) * 2]\n return new Raycaster().setFromCamera(ndc, this.camera).ray\n }\n\n /** The last frame, when it is big enough that picking on the GPU pays. */\n #gpuFrame() {\n const frame = this.lastFrame\n if (!frame) return null\n let work = 0\n for (const { node, geometry, instances } of [...frame.opaque, ...frame.transparent]) {\n const mode = /** @type {any} */ (node).drawMode\n work += instances ? instances.count : mode === 'points' ? geometry.drawnVertices : mode === 'lines' ? geometry.drawnCount / 2 : geometry.drawnCount / 3\n }\n return work > GPU_PICKING ? frame : null\n }\n\n /**\n * A GPU hit made exact: the ray against just that instance, point or segment, for the point,\n * face, normal and uv.\n * @param {import('./webgl/picking.js').GPUHit} found @param {FrameDescription} frame\n * @returns {Hit}\n */\n #exact(found, frame) {\n const node = /** @type {any} */ (found.item.node)\n const raycaster = new Raycaster().setFromCamera(found.ndc, this.camera)\n const hit = raycaster.intersectElement(node, found.element)\n if (hit) return hit\n // the ray grazed an edge the GPU drew: place the hit at the depth the GPU found\n const inverse = new Mat4().copy(frame.camera.viewProjection).invert()\n const point = new Vec3(found.ndc[0], found.ndc[1], found.ndc[2]).applyMatrix4(inverse)\n const instanced = 'instanceMatrices' in node, element = found.element\n const indexed = instanced || node.drawMode !== 'triangles'\n return { node, point, distance: point.distanceTo(raycaster.ray.origin), normal: null, face: indexed && !instanced ? element : null,\n instance: instanced ? element : null, uv: null, datum: node.datumAt(indexed ? element : null) }\n }\n\n /**\n * Where a world position is on the canvas - CSS pixels from its top left - with its depth (0 at\n * the near plane, 1 at the far) and whether it's in view: for placing HTML of your own over the\n * scene, beside what it's about.\n *\n * const { x, y } = view.project(cube.worldPosition)\n * @param {Vec3Input} point\n * @returns {{ x: number, y: number, depth: number, visible: boolean }}\n */\n project(point) {\n const { ndc: [x, y, z], visible } = toScreen(Vec3.fromInput(point, 'View'), this.#viewProjection())\n return { x: (x * 0.5 + 0.5) * this.#width, y: (0.5 - y * 0.5) * this.#height, depth: z * 0.5 + 0.5, visible }\n }\n\n /**\n * The rectangle on the canvas that a node, a box or (with no argument) the whole scene covers - CSS\n * pixels, from the corners of each thing the camera draws of it (as node.boundsFrom counts them).\n * Null when there's nothing there, or part of it is behind the camera.\n *\n * const { left, top, width } = view.screenBounds(model) // put a title above it\n * @param {Node | Box3} [target]\n * @returns {{ left: number, top: number, right: number, bottom: number, width: number, height: number } | null}\n */\n screenBounds(target = this.scene) {\n const points = target instanceof Box3 ? corners(target) : drawnPoints(target, this.camera)\n if (!points.length) return null\n let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity\n for (const point of points) {\n const { x, y, depth } = this.project(point)\n if (!(depth >= 0 && depth <= 1)) return null\n left = Math.min(left, x)\n right = Math.max(right, x)\n top = Math.min(top, y)\n bottom = Math.max(bottom, y)\n }\n return { left, top, right, bottom, width: right - left, height: bottom - top }\n }\n\n /** The camera's world to clip space matrix, up to date. @returns {Mat4} */\n #viewProjection() {\n const camera = this.camera\n camera.updateWorld()\n return new Mat4().multiplyMatrices(camera.projectionMatrix, camera.viewMatrix)\n }\n\n /**\n * Everything inside an area of the canvas, nearest first: a box `{ x, y, width, height }` or a\n * lasso of `[x, y]` points, CSS pixels from the canvas's top left. Each point, instance and line\n * segment is its own hit, found by where it is (a mesh by its middle) - hidden behind others or\n * not - so a box dragged over a scatter selects that region of it.\n *\n * const picked = view.pickArea({ x: 40, y: 30, width: 200, height: 120 }).map((h) => h.datum)\n * @param {import('./area.js').PickArea} area\n * @returns {Hit[]}\n */\n pickArea(area) {\n this.scene.updateWorldTree()\n return pickArea(this.scene, this.camera, this.#viewProjection(), this.#width, this.#height, area)\n }\n\n /** Every hit under a canvas position, nearest first. @param {number | MouseEvent} x @param {number} [y] @returns {Hit[]} */\n pickAll(x, y) {\n if (typeof x === 'object') {\n const rect = this.canvas.getBoundingClientRect()\n y = x.clientY - rect.top\n x = x.clientX - rect.left\n }\n const ndc = [(x / this.#width) * 2 - 1, 1 - (/** @type {number} */ (y) / this.#height) * 2]\n const raycaster = new Raycaster().setFromCamera(ndc, this.camera)\n // a few pixels' tolerance for points and lines, as world units at the target's distance\n const cam = /** @type {any} */ (this.camera)\n const distance = cam.position.distanceTo(cam.target ?? [0, 0, 0])\n const worldPerPixel = cam.constructor.type === 'orthographic-camera'\n ? cam.height / this.#height\n : 2 * distance * Math.tan(cam.fov * Math.PI / 360) / this.#height\n raycaster.threshold = 4 * worldPerPixel\n this.scene.updateWorldTree()\n return raycaster.intersect(this.scene)\n }\n\n /**\n * Listen for clicks on, or hovering over, the scene. Handlers get the hit (with .node, .instance\n * and .datum) or null for empty space. 'hover' fires when the thing under the pointer changes,\n * including to null when it leaves. Returns a function that removes the handler.\n *\n * view.on('click', (hit) => hit && select(hit.datum))\n * @param {ViewEvent} type\n * @param {ViewHandler} fn\n * @returns {() => void}\n */\n on(type, fn) {\n if (!(type in this.#handlers)) {\n const hint = EVENT_HINTS[type]\n if (hint) fail('View', `on('${type}') - use '${hint}'${hint === 'hover' ? ', which fires as the thing under the pointer changes (null when it leaves)' : ''}`)\n checkOneOf('View', 'event', type, ['click', 'hover'])\n }\n if (typeof fn !== 'function') fail('View', `on('${type}', fn) needs a function, got ${describe(fn)}`)\n const set = this.#handlers[type]\n set.add(fn)\n this.#pickPending = true\n return () => set.delete(fn)\n }\n\n /**\n * Show a tooltip by the pointer for whatever it is over. The function gets the hit and returns\n * text (new lines kept), an element, or { title, rows } - rows as { name: value } - or null for\n * none. Style it with the .phoria-tooltip class. Pass null to remove it.\n *\n * view.tooltip((hit) => ({ title: hit.datum.name, rows: { Sales: hit.datum.sales } }))\n * @param {((hit: Hit) => TooltipContent) | null} content\n * @param {{ className?: string }} [options]\n * @returns {this}\n */\n tooltip(content, { className } = {}) {\n if (content !== null && typeof content !== 'function') fail('View', `tooltip() takes a function (hit) => text, or null, got ${describe(content)}`)\n this.#tooltipContent = content\n if (className !== undefined) this.#tooltipClass = className\n if (this.#tooltip) this.#tooltip.el.className = `phoria-tooltip${this.#tooltipClass ? ` ${this.#tooltipClass}` : ''}`\n if (content) this.#loadTooltip()\n this.#pickPending = true\n return this\n }\n\n // the tooltip's code loads when first needed, so apps without one don't carry it\n #loadTooltip() {\n if (this.#tooltipLoading) return\n this.#tooltipLoading = true\n import('./tooltip.js').then(({ Tooltip }) => {\n if (this.#disposed) return\n this.#tooltip = new Tooltip((hit) => this.#tooltipFor(hit)?.(hit), this.#tooltipClass)\n this.#pickPending = true\n this.#schedule()\n })\n }\n\n /** @param {true | KeyboardOptions} options */\n #loadKeyboard(options) {\n if (options !== true && (typeof options !== 'object' || options === null || Array.isArray(options))) {\n fail('View', `'keyboard' is true, false or { label: (hit) => text }, got ${describe(options)}`)\n }\n const o = options === true ? {} : options\n checkOptions('View', o, ['label'], { describe: \"use 'label: (hit) => text'\", text: \"use 'label: (hit) => text'\" }, 'keyboard')\n if (o.label !== undefined && typeof o.label !== 'function') fail('View', `keyboard.label is a function (hit) => text, got ${describe(o.label)}`)\n import('./keyboard.js').then(({ Keyboard }) => {\n if (this.#disposed) return\n this.#keyboard = new Keyboard(this, {\n focus: (hit) => {\n this.#keyFocus = hit\n this.#pickPending = true\n this.invalidate()\n },\n press: (hit) => {\n for (const fn of handlersAbove(hit.node, 'click')) fn(hit)\n for (const fn of this.#handlers.click) fn(hit, null)\n },\n tooltip: (hit) => this.#tooltipFor(hit)?.(hit),\n viewWide: () => this.#handlers.hover.size > 0 || this.#handlers.click.size > 0 || !!this.#tooltipContent,\n }, o)\n this.#keyboard.setDescription(this.#description)\n })\n }\n\n /** Where the keyboard's focus shows - its middle, on screen - in place of the pointer. @param {Hit} hit */\n #keyAt(hit) {\n const { x, y } = this.project(hit.point), rect = this.canvas.getBoundingClientRect()\n return { x, y, clientX: rect.left + x, clientY: rect.top + y, event: null }\n }\n\n /** The nearest node tooltip above the hit, or the View's. @param {Hit} hit */\n #tooltipFor(hit) {\n for (let n = /** @type {any} */ (hit.node); n; n = n.parent) if (n.tooltip) return n.tooltip\n return this.#tooltipContent\n }\n\n /**\n * The current picture as an image file (PNG by default), with the visible labels painted in.\n *\n * const png = await view.toImage()\n * @param {ImageOptions} [options]\n * @returns {Promise<Blob>}\n */\n async toImage(options) {\n const { snapshot } = await import('./snapshot.js')\n // draw - complete, shaders and all - and read back in the same task, while the drawing\n // buffer is still there\n this.#render(true)\n return snapshot(this.canvas, this.#labels.shown, options ?? {}, this.#labels.leaders)\n }\n\n /**\n * A plain-text report of what the view is drawing - camera, what is drawn and culled, bounds,\n * lights, labels - with warnings for the usual reasons a picture is wrong (\"nothing in view\").\n * Draws a fresh frame first.\n *\n * console.log(await view.explain())\n * @returns {Promise<string>}\n */\n async explain() {\n const { explain } = await import('./explain.js')\n const frame = this.render()\n let nodes = 0\n const notes = []\n this.scene.traverse((n) => {\n nodes++\n // nodes that can describe themselves (charts) add a line each\n if (n !== this.scene && typeof (/** @type {any} */ (n)).explain === 'function') notes.push(/** @type {any} */ (n).explain())\n })\n // how much of the view the scene covers: what is drawn, projected - a share of each side\n const drawn = this.scene.boundsFrom(this.camera), onScreen = this.screenBounds(this.scene)\n const fills = onScreen ? { height: onScreen.height / this.#height, width: onScreen.width / this.#width } : null\n return explain({\n notes, fills,\n width: this.#width, height: this.#height, pixelRatio: this.#pixelRatio, renderMode: this.renderMode, running: this.#running,\n sharedContext: this.renderer.shared,\n frame, labels: this.#labelStats, bounds: drawn, nodes, autoLight: this.autoLight,\n contextLost: !!this.renderer.gl?.isContextLost?.(),\n interaction: { hover: this.#handlers.hover.size, click: this.#handlers.click.size, tooltip: !!this.#tooltipContent, highlight: !!this.#highlight,\n keyboard: !!this.#keyboard, reducedMotion: this.reducedMotion, description: this.canvas.getAttribute?.('aria-label') ?? this.#description },\n })\n }\n\n /**\n * Stop the loop, remove listeners, labels and the tooltip, and free GPU resources - the context\n * itself when the view has its own, or what only this view drew when it shares one.\n */\n dispose() {\n if (this.#disposed) return\n this.#disposed = true\n this.#running = false\n cancelAnimationFrame(this.#rafId)\n for (const fn of this.#cleanup) fn()\n this.controls?.dispose()\n this.#labels.dispose()\n this.#tooltip?.dispose()\n this.#keyboard?.dispose()\n if (this.#description !== null && !this.#keyboard) this.description = null\n this.renderer.dispose(this.scene)\n if (this.#ownContext) ownContexts--\n if (this.#ownCanvas) this.canvas.remove()\n }\n\n // widen or narrow the view so the framing chosen with `framing.keep` survives a change of shape\n #keepFraming() {\n const cam = /** @type {any} */ (this.#camera)\n if (!this.#designed) this.#designed = cam.aspect\n const scale = framingScale(this.#keep, this.#designed, cam.aspect)\n const k = scale / this.#applied\n this.#applied = scale\n if (Math.abs(k - 1) < 1e-9) return\n if (cam.constructor.type === 'orthographic-camera') cam.height *= k\n else if (cam.target) {\n const offset = cam.position.clone().sub(cam.target).multiplyScalar(k)\n cam.position.copy(cam.target).add(offset)\n } else {\n // no target to move away from: widen the field of view instead\n cam.fov = Math.min(170, 2 * Math.atan(Math.tan(cam.fov * Math.PI / 360) * k) * 360 / Math.PI)\n }\n }\n\n // One requestAnimationFrame per frame at most, and none while the canvas is off screen or (in\n // manual mode) while there is nothing to do.\n #schedule() {\n if (this.#rafId || this.#disposed || !this.#onScreen) return\n if (this.renderMode === 'manual' && !(this.#running && this.#onFrame) && !this.#dirty && !this.#pickPending) return\n this.#rafId = requestAnimationFrame(this.#tick)\n }\n\n /** @param {number} now */\n #tick = (now) => {\n this.#rafId = 0\n const dt = this.#lastTime ? Math.min(this.maxDelta, (now - this.#lastTime) / 1000) : 0\n this.#lastTime = now\n try {\n if (this.#running) {\n this.time += dt\n this.#onFrame?.(dt, this.time)\n this.scene.motionReduced = this.reducedMotion\n this.scene.update(dt, this.time)\n }\n this.#updateControls(dt)\n if (this.#pickPending) this.#updateHover()\n const draw = this.#dirty || this.renderMode === 'always' ||\n (this.renderMode === 'auto' && this.#watch.changed(this.scene, this.camera))\n if (draw) this.render()\n } finally {\n // the next frame comes even if this one threw - the error still reaches the console, but one\n // bad handler doesn't freeze the view. In manual mode, sleep until something asks for a frame\n if (this.renderMode !== 'manual' || (this.#running && this.#onFrame) || this.#dirty || this.#pickPending) this.#schedule()\n }\n }\n\n #needsHover() {\n return this.#handlers.hover.size > 0 || !!this.#tooltipContent || !!this.#highlight || this.#handlers.click.size > 0 ||\n !!this.lastFrame?.interactive\n }\n\n // pick under the pointer and tell everyone when the thing under it changes - on the GPU without\n // waiting for it in big scenes, so hovering never stalls a frame\n #updateHover() {\n this.#pickPending = false\n if (!this.#needsHover()) return\n const p = this.#pointer\n // what the keyboard stepped to is shown until the pointer moves\n if (this.#keyFocus) return this.#setHovered(this.#keyFocus, this.#keyAt(this.#keyFocus))\n if (this.#labelHover) return this.#setHovered(this.#labelHover)\n if (!p || this.#dragging) return this.#setHovered(null)\n const frame = this.#gpuFrame()\n if (frame && this.#hoverBusy) {\n // look again when the request out now lands\n this.#pickPending = true\n return\n }\n const request = frame ? this.renderer.pickAsync(frame, p.x, p.y) : undefined\n if (!request) return this.#setHovered(this.pick(p.x, p.y))\n this.#hoverBusy = true\n request.then((found) => {\n this.#hoverBusy = false\n if (this.#disposed) return\n // the pointer may have gone, or moved on (then a newer pick is due)\n this.#setHovered(this.#labelHover ?? (found && this.#pointer ? this.#exact(found, frame) : null))\n this.#schedule()\n })\n }\n\n /**\n * @param {Hit | null} hit\n * @param {{ clientX: number, clientY: number, event: PointerEvent | null } | null} [p] where it is shown - the pointer, or the keyboard's focus\n */\n #setHovered(hit, p = this.#pointer) {\n const before = this.#hovered\n // the same thing under the pointer: the same node, instance and row of data - a line's segments\n // and a surface's rows are told apart by their data, without a plain mesh changing per triangle\n const same = before === hit || (before && hit && before.node === hit.node && before.instance === hit.instance &&\n before.datum === hit.datum && (/** @type {any} */ (hit.node).drawMode !== 'points' || before.face === hit.face))\n this.#hovered = hit\n if (p && hit && this.#tooltip) this.#tooltip.show(hit, p.clientX, p.clientY)\n else this.#tooltip?.hide()\n if (same) return\n if (this.#highlightFor(before) || this.#highlightFor(hit)) this.invalidate()\n if (this.#handlers.click.size || this.lastFrame?.interactive) {\n this.canvas.style.cursor = hit && nearestAbove(hit.node, 'onDrag') ? 'grab' : hit && this.#clickable(hit) ? 'pointer' : ''\n }\n // node handlers: those that lose the pointer hear null, those that gain or keep it hear the hit\n const was = handlersAbove(before?.node, 'hover'), now = handlersAbove(hit?.node, 'hover')\n for (const fn of was) if (!now.includes(fn)) fn(null)\n for (const fn of now) fn(hit)\n for (const fn of this.#handlers.hover) fn(hit, p?.event ?? null)\n }\n\n /**\n * The pointer on a label that answers it: a click or hover there is one on what the label labels.\n * @param {'click' | 'over' | 'out'} type @param {import('./frame.js').FrameLabel} label @param {MouseEvent | null} e\n */\n #labelPointer(type, label, e) {\n const node = /** @type {any} */ (label.node), index = label.index\n const points = index !== null && node.drawMode === 'points'\n /** @type {Hit} */\n const hit = { node, point: label.position.clone(), distance: label.position.distanceTo(this.camera.worldPosition), normal: null,\n face: points ? index : null, instance: index !== null && !points ? index : null, uv: null, datum: node.datumAt?.(index) ?? null }\n if (type === 'click') {\n for (const fn of handlersAbove(node, 'click')) fn(hit)\n for (const fn of this.#handlers.click) fn(hit, e)\n return\n }\n this.#labelHover = type === 'over' ? hit : null\n if (e) {\n const rect = this.canvas.getBoundingClientRect()\n this.#pointer = { x: e.clientX - rect.left, y: e.clientY - rect.top, clientX: e.clientX, clientY: e.clientY, event: /** @type {PointerEvent} */ (e) }\n }\n if (type === 'out') this.#pointer = null\n this.#pickPending = true\n this.#schedule()\n }\n\n /** Does clicking this hit do anything? @param {Hit} hit */\n #clickable(hit) {\n return this.#handlers.click.size > 0 || handlersAbove(hit.node, 'click').length > 0\n }\n\n /** @param {Hit | null} hit @returns {FrameHighlight | null} */\n #highlightFor(hit) {\n if (!hit) return null\n // the nearest colour wins - or the nearest false, which tints nothing - and the nearest\n // highlightWhole is what is tinted as one\n let color = null, whole = null\n for (let n = /** @type {any} */ (hit.node); n; n = n.parent) {\n color ??= n.highlight\n whole ??= n.highlightWhole ? n : null\n }\n color ??= this.#highlight\n // the keyboard's focus always shows\n if (!color && hit === this.#keyFocus) color = FOCUS_COLOR\n if (!color) return null\n const node = /** @type {any} */ (hit.node)\n if (whole) {\n /** @type {Set<Node>} */\n const nodes = new Set()\n whole.traverse((n) => { nodes.add(n) })\n return { node, index: null, nodes, color, amount: HIGHLIGHT_AMOUNT }\n }\n const index = hit.instance ?? (node.drawMode === 'points' ? hit.face : null)\n return { node, index, color, amount: HIGHLIGHT_AMOUNT }\n }\n\n // hide labels that asked to be hidden behind geometry, by casting a ray to each\n /** @param {FrameDescription} frame */\n #occlude(frame) {\n const labels = /** @type {(import('./frame.js').FrameLabel & { occluded?: boolean })[]} */ (frame.labels)\n // a label waiting to be zoomed in to won't show either way, so it needs no ray\n const halfHeight = this.height / 2\n const testing = labels.filter((l) => l.style.occlude && l.visible && !(l.style.minScale && l.scale * halfHeight < l.style.minScale))\n if (!testing.length) return\n // what this frame drew hides what is behind it - the same surfaces the picture shows, each placed\n // once for all the rays, which ask only whether anything is nearer than their label\n const solids = Raycaster.solids([...frame.opaque, ...frame.transparent])\n const raycaster = new Raycaster()\n for (const label of testing) {\n raycaster.setFromCamera(label.ndc, this.camera)\n const distance = label.position.distanceTo(raycaster.ray.origin)\n // only solid surfaces hide labels, and not the instance or point being labelled\n label.occluded = raycaster.blocked(solids, distance * 0.995, label.node, label.index)\n }\n }\n\n #listen() {\n const canvas = this.canvas\n const at = (e) => {\n const rect = canvas.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top, clientX: e.clientX, clientY: e.clientY, event: e }\n }\n const move = (e) => {\n // the pointer takes over from the keyboard\n if (this.#keyFocus) this.#keyboard?.clear()\n this.#pointer = at(e)\n const press = this.#press\n if (press && press.id === e.pointerId && !press.moved && Math.hypot(this.#pointer.x - press.x, this.#pointer.y - press.y) >= DRAG_START) press.moved = true\n if (this.#drag) this.#moveDrag(e, this.#pointer)\n else this.#orbitPointer?.move(e)\n this.#dragging = e.buttons !== 0\n if (this.#dragging) this.#tooltip?.hide()\n else this.#tooltip?.move(e.clientX, e.clientY)\n if (!this.#needsHover()) return\n this.#pickPending = true\n this.#schedule()\n }\n const leave = () => {\n this.#pointer = null\n this.#pickPending = true\n this.#schedule()\n }\n const up = (e) => {\n if (this.#drag) this.#endDrag(e)\n else this.#orbitPointer?.up(e)\n this.#dragging = false\n this.#pickPending = true\n this.#schedule()\n }\n // every press starts here: on something with onDrag it drags that, anywhere else it orbits - and\n // one that moves far enough, either way, isn't a click\n const down = (e) => {\n // a new press replaces a drag whose letting go never arrived (released outside the window, say)\n if (this.#drag?.id === e.pointerId) return\n // and takes the camera from a glide\n this.#flight = null\n this.#drag = null\n const pressedAt = at(e)\n this.#press = { id: e.pointerId, x: pressedAt.x, y: pressedAt.y, moved: false }\n const hit = this.lastFrame?.draggable && !(e.pointerType === 'mouse' && e.button !== 0) ? this.pick(e) : null\n const node = hit && nearestAbove(hit.node, 'onDrag')\n if (!hit || !node) {\n this.#orbitPointer?.down(e)\n return\n }\n try { canvas.setPointerCapture(e.pointerId) } catch { /* drags still work inside the canvas */ }\n const p = at(e)\n const start = hit.point.clone()\n /** @type {import('./scene/Node.js').Drag} */\n const drag = { phase: 'start', hit, node, ray: this.rayAt(p.x, p.y), plane: { normal: new Vec3(0, 1, 0), point: start.clone() },\n start, point: start.clone(), delta: new Vec3(), event: e }\n this.#drag = { drag, id: e.pointerId, x: p.x, y: p.y, press: drag.ray, started: false }\n }\n const click = (e) => {\n // the end of a drag - of a node or of the orbit - isn't a click\n if (this.#press?.moved) {\n this.#press = null\n return\n }\n if (!this.#handlers.click.size && !this.lastFrame?.interactive) return\n const hit = this.pick(e)\n if (hit) for (const fn of handlersAbove(hit.node, 'click')) fn(hit)\n for (const fn of this.#handlers.click) fn(hit, e)\n }\n canvas.addEventListener('pointerdown', down)\n canvas.addEventListener('pointermove', move)\n canvas.addEventListener('pointerleave', leave)\n canvas.addEventListener('pointerup', up)\n canvas.addEventListener('pointercancel', up)\n canvas.addEventListener('click', click)\n const wheel = () => { this.#flight = null }\n canvas.addEventListener('wheel', wheel, { passive: true })\n this.#cleanup.push(() => {\n canvas.removeEventListener('wheel', wheel)\n canvas.removeEventListener('pointerdown', down)\n canvas.removeEventListener('pointermove', move)\n canvas.removeEventListener('pointerleave', leave)\n canvas.removeEventListener('pointerup', up)\n canvas.removeEventListener('pointercancel', up)\n canvas.removeEventListener('click', click)\n })\n\n if (typeof ResizeObserver !== 'undefined') {\n const resize = new ResizeObserver(() => {\n this.resize()\n // draw straight away: a resized canvas is blank until the next draw\n this.render()\n })\n resize.observe(canvas)\n this.#cleanup.push(() => resize.disconnect())\n }\n // the system's reduced-motion setting, followed as it changes\n const motion = globalThis.matchMedia?.('(prefers-reduced-motion: reduce)')\n if (motion) {\n const follow = () => {\n this.#systemReduced = motion.matches\n this.invalidate()\n }\n this.#systemReduced = motion.matches\n motion.addEventListener?.('change', follow)\n this.#cleanup.push(() => motion.removeEventListener?.('change', follow))\n }\n // an off-screen view (a dashboard tile scrolled away) does no work at all\n if (typeof IntersectionObserver !== 'undefined') {\n const visible = new IntersectionObserver(([entry]) => {\n this.#onScreen = entry.isIntersecting\n if (this.#onScreen) this.invalidate()\n })\n visible.observe(canvas)\n this.#cleanup.push(() => visible.disconnect())\n }\n }\n\n /**\n * The pointer moved while something is pressed: once it has moved far enough to be a drag, tell\n * the node's handler it started, then where it is on the plane each move.\n * @param {PointerEvent} e @param {{ x: number, y: number }} p\n */\n #moveDrag(e, p) {\n const d = this.#drag\n if (!d || e.pointerId !== d.id) return\n const { drag } = d\n drag.event = e\n drag.ray = this.rayAt(p.x, p.y)\n if (!d.started) {\n if (Math.hypot(p.x - d.x, p.y - d.y) < DRAG_START) return\n d.started = true\n this.canvas.style.cursor = 'grabbing'\n drag.phase = 'start'\n const plane = drag.plane\n drag.node.onDrag?.(drag)\n // a handler that chose another plane drags across that, from where the press meets it\n if (drag.plane !== plane || !drag.plane.point.equals(plane.point) || !drag.plane.normal.equals(plane.normal)) {\n drag.plane = { normal: Vec3.fromInput(drag.plane.normal, 'Drag').normalize(), point: Vec3.fromInput(drag.plane.point, 'Drag') }\n const t = d.press.intersectPlane(drag.plane.normal, drag.plane.point)\n if (t !== null) drag.start.copy(d.press.at(t))\n }\n }\n drag.phase = 'move'\n const t = drag.ray.intersectPlane(drag.plane.normal, drag.plane.point)\n if (t !== null) {\n drag.point = drag.ray.at(t)\n drag.delta.copy(drag.point).sub(drag.start)\n } else drag.point = null\n drag.node.onDrag?.(drag)\n this.invalidate()\n }\n\n /** The pointer let go: a drag ends, and the click that follows isn't one. @param {PointerEvent} e */\n #endDrag(e) {\n const d = this.#drag\n if (!d || e.pointerId !== d.id) return\n this.#drag = null\n try { this.canvas.releasePointerCapture(e.pointerId) } catch { /* already gone */ }\n if (!d.started) return\n d.drag.phase = 'end'\n d.drag.event = e\n d.drag.node.onDrag?.(d.drag)\n this.canvas.style.cursor = ''\n this.invalidate()\n }\n\n /** @param {FrameDescription} frame */\n #addAutoLights(frame) {\n if (!this.#noted) {\n this.#noted = true\n console.info('phoria2: the scene has no lights, so the View is lighting it (autoLight: false turns this off)')\n }\n const hemi = this.#autoSky, sun = this.#autoSun\n frame.lights.push(\n { kind: 'hemisphere', node: hemi, color: hemi.sky, ground: hemi.ground, intensity: hemi.intensity },\n { kind: 'directional', node: sun, color: sun.color, intensity: sun.intensity, direction: sun.worldDirection })\n }\n}\n\n/** Where a camera is and looks, to tell whether the app has moved it. @param {any} camera @returns {number[]} */\nfunction cameraPlace(camera) {\n return [...camera.position, ...(camera.target ?? []), camera.fov ?? camera.height]\n}\n/** @param {number[]} a @param {number[] | null} b */\nconst samePlace = (a, b) => !!b && a.length === b.length && a.every((v, i) => v === b[i])\n\n/** A box's eight corners - one point when it is a point. @param {Box3} box @returns {number[][]} */\nfunction corners(box) {\n if (box.isEmpty()) return []\n if (box.min.equals(box.max)) return [box.min.toArray()]\n const out = []\n for (let i = 0; i < 8; i++) out.push([i & 1 ? box.max[0] : box.min[0], i & 2 ? box.max[1] : box.min[1], i & 4 ? box.max[2] : box.min[2]])\n return out\n}\n\n// past this many instances or vertices, a drawable is fitted by the box round it all\nconst FIT_DETAIL = 4000\n\n/**\n * The points a camera draws of a subtree, to fit a view round: the corners of each thing's box, so\n * the empty space between things doesn't count as filled - and closer still, the corners of each\n * instance and the vertices of lines and points, so a cloud of them isn't fitted by the corners of\n * the cube round it.\n * @param {Node} node @param {Camera} camera @returns {number[][]}\n */\nfunction drawnPoints(node, camera) {\n node.updateWorld()\n /** @type {number[][]} */\n const points = []\n node.eachShownTo(camera, (n) => {\n const d = /** @type {any} */ (n)\n if ('instanceMatrices' in d && d.count <= FIT_DETAIL) {\n d.eachInstanceBox((x0, y0, z0, x1, y1, z1) => { points.push(...corners(new Box3([x0, y0, z0], [x1, y1, z1]))) })\n } else if ((d.drawMode === 'lines' || d.drawMode === 'points') && d.geometry.vertexCount <= FIT_DETAIL) {\n // the vertices drawn - every one, when indices pick them\n const g = d.geometry, p = g.positions, m = d.worldMatrix, count = g.indices ? g.vertexCount : g.drawnVertices\n for (let i = 0; i < count; i++) {\n const x = p[i * 3], y = p[i * 3 + 1], z = p[i * 3 + 2]\n points.push([m[0] * x + m[4] * y + m[8] * z + m[12], m[1] * x + m[5] * y + m[9] * z + m[13], m[2] * x + m[6] * y + m[10] * z + m[14]])\n }\n } else points.push(...corners(n.expandBounds(new Box3())))\n })\n return points\n}\n\n/** The nearest node at or above this one with a handler of this kind. @param {any} node @param {string} key */\nfunction nearestAbove(node, key) {\n for (let n = node; n; n = n.parent) if (n[key]) return n\n return null\n}\n\n/** @typedef {{ position: Vec3, target: Vec3, height?: number }} Place */\n/** @typedef {{ from: Place, to: Place, time: number, duration: number }} Flight */\n\n/** Where a camera is, and an orthographic one's view height. @param {any} cam @returns {Place} */\nfunction placeOf(cam) {\n return { position: cam.position.clone(), target: (cam.target ?? new Vec3()).clone(), height: cam.height }\n}\n\n/** @param {any} cam @param {Place} place */\nfunction setPlace(cam, place) {\n cam.position.copy(place.position)\n setTarget(cam, place.target)\n if (place.height !== undefined) cam.height = place.height\n}\n\n/** Move a camera's target, keeping the one it has. @param {any} cam @param {Vec3} target */\nfunction setTarget(cam, target) {\n if (cam.target) cam.target.copy(target)\n else cam.target = target.clone()\n}\n\n/**\n * Part way from one unit direction to another, along the great circle - by way of a side, when they\n * are opposite and every way round is as short.\n * @param {Vec3} a @param {Vec3} b @param {number} t\n * @returns {Vec3}\n */\nfunction turnBetween(a, b, t) {\n const cos = Math.max(-1, Math.min(1, a.dot(b)))\n if (cos > 0.9999) return a.clone().lerp(b, t).normalize()\n if (cos < -0.9999) {\n const side = Math.abs(a[1]) < 0.9 ? new Vec3(0, 1, 0) : new Vec3(1, 0, 0)\n const mid = a.clone().cross(side).normalize()\n return t < 0.5 ? turnBetween(a, mid, t * 2) : turnBetween(mid, b, t * 2 - 1)\n }\n const angle = Math.acos(cos), s = Math.sin(angle)\n return a.clone().multiplyScalar(Math.sin((1 - t) * angle) / s).add(b.clone().multiplyScalar(Math.sin(t * angle) / s))\n}\n\n/**\n * The handlers a label answers: those of a Label node that has its own, or those of the instance or\n * point it labels.\n * @param {import('./frame.js').FrameLabel} label @param {'hover' | 'click'} event @returns {Function[]}\n */\nfunction labelHandlers(label, event) {\n if (label.index === null && !label.node.handlersFor(event).length) return []\n return handlersAbove(label.node, event)\n}\n\n/**\n * A node's hover or click handlers and its ancestors', nearest first: each one's own, then its listeners.\n * @param {any} node @param {'hover' | 'click'} event @returns {Function[]}\n */\nfunction handlersAbove(node, event) {\n const list = []\n for (let n = node; n; n = n.parent) list.push(...n.handlersFor(event))\n return list\n}\n\n/** @param {HTMLCanvasElement | string | undefined} canvas @returns {HTMLCanvasElement} */\nfunction resolveCanvas(canvas) {\n if (canvas === undefined) {\n const c = document.createElement('canvas')\n Object.assign(c.style, { position: 'fixed', inset: '0', width: '100vw', height: '100vh', display: 'block' })\n document.body.append(c)\n return c\n }\n if (typeof canvas === 'string') {\n const el = document.querySelector(canvas)\n if (!el) fail('View', `canvas '${canvas}' not found`)\n if (!(el instanceof HTMLCanvasElement)) fail('View', `'${canvas}' is a <${el.tagName.toLowerCase()}>, not a <canvas>`)\n return el\n }\n if (!(canvas instanceof HTMLCanvasElement)) fail('View', `'canvas' must be a <canvas> element or a selector, got ${describe(canvas)}`)\n return canvas\n}\n","// Filling flat outlines with triangles: ear clipping, with holes bridged into the outline first so\n// the whole thing is one polygon. Plenty for the hand-made shapes extrude() takes - a few hundred\n// points - without a library.\n\n/** @typedef {[number, number]} Point2 */\n\n/** Twice the signed area: positive when the points run counter-clockwise. @param {Point2[]} points */\nexport function area(points) {\n let a = 0\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n a += (points[j][0] - points[i][0]) * (points[j][1] + points[i][1])\n }\n return a\n}\n\n/**\n * Triangles filling an outline with holes, as triples of indices into the outline's points\n * followed by each hole's, wound counter-clockwise. The outline may run either way round, and so\n * may the holes.\n * @param {Point2[]} outline\n * @param {Point2[][]} [holes]\n * @returns {number[]}\n */\nexport function triangulate(outline, holes = []) {\n // every point once, by index: the outline's, then each hole's in turn\n /** @type {Point2[]} */\n const points = [...outline]\n /** @type {number[]} */\n let ring = outline.map((_, i) => i)\n if (area(outline) < 0) ring.reverse()\n // holes go in clockwise, rightmost first, each bridged from its rightmost point\n const placed = holes.map((hole) => {\n const start = points.length\n points.push(...hole)\n const ids = hole.map((_, i) => start + i)\n if (area(hole) > 0) ids.reverse()\n return ids\n }).sort((a, b) => maxX(points, b) - maxX(points, a))\n for (const hole of placed) ring = bridge(points, ring, hole, placed)\n return clip(points, ring)\n}\n\n/** @param {Point2[]} points @param {number[]} ids */\nconst maxX = (points, ids) => Math.max(...ids.map((i) => points[i][0]))\n\n/**\n * Join a hole into the ring: from the hole's rightmost point to the nearest point of the ring it\n * can see, there and back, so the ring runs round the hole too.\n * @param {Point2[]} points @param {number[]} ring @param {number[]} hole @param {number[][]} holes\n * @returns {number[]}\n */\nfunction bridge(points, ring, hole, holes) {\n let m = 0\n hole.forEach((id, k) => { if (points[id][0] > points[hole[m]][0]) m = k })\n const M = points[hole[m]]\n // edges a bridge mustn't cross: the ring's and every hole's\n /** @type {[Point2, Point2][]} */\n const edges = []\n for (const ids of [ring, ...holes]) ids.forEach((id, k) => edges.push([points[id], points[ids[(k + 1) % ids.length]]]))\n let best = -1, bestD = Infinity\n ring.forEach((id, k) => {\n const P = points[id]\n const d = (P[0] - M[0]) ** 2 + (P[1] - M[1]) ** 2\n // nearer first, preferring points to the right as the usual bridge does\n const score = d * (P[0] >= M[0] ? 1 : 4)\n if (score >= bestD) return\n if (edges.some(([a, b]) => crosses(M, P, a, b))) return\n best = k\n bestD = score\n })\n if (best < 0) best = 0\n const around = [...hole.slice(m), ...hole.slice(0, m)]\n return [...ring.slice(0, best + 1), ...around, hole[m], ring[best], ...ring.slice(best + 1)]\n}\n\n/** Do segments pq and ab cross, other than at shared ends? @param {Point2} p @param {Point2} q @param {Point2} a @param {Point2} b */\nfunction crosses(p, q, a, b) {\n if (same(p, a) || same(p, b) || same(q, a) || same(q, b)) return false\n const d1 = cross(a, b, p), d2 = cross(a, b, q), d3 = cross(p, q, a), d4 = cross(p, q, b)\n return d1 * d2 < 0 && d3 * d4 < 0\n}\n\n/** @param {Point2} a @param {Point2} b */\nconst same = (a, b) => a[0] === b[0] && a[1] === b[1]\n\n/** Positive when a, b, c turn counter-clockwise. @param {Point2} a @param {Point2} b @param {Point2} c */\nconst cross = (a, b, c) => (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0])\n\n/**\n * Clip ears off a counter-clockwise ring until it is all triangles.\n * @param {Point2[]} points @param {number[]} ring\n * @returns {number[]}\n */\nfunction clip(points, ring) {\n const left = [...ring], out = []\n while (left.length > 3) {\n let cut = -1\n for (let k = 0; k < left.length && cut < 0; k++) if (isEar(points, left, k)) cut = k\n // nothing clean to cut (a sliver, or points that overlap): take the first convex corner, or any\n if (cut < 0) for (let k = 0; k < left.length && cut < 0; k++) if (convex(points, left, k)) cut = k\n if (cut < 0) cut = 0\n const n = left.length\n out.push(left[(cut + n - 1) % n], left[cut], left[(cut + 1) % n])\n left.splice(cut, 1)\n }\n if (left.length === 3) out.push(...left)\n return out\n}\n\n/** @param {Point2[]} points @param {number[]} left @param {number} k */\nfunction convex(points, left, k) {\n const n = left.length\n return cross(points[left[(k + n - 1) % n]], points[left[k]], points[left[(k + 1) % n]]) > 0\n}\n\n/** A convex corner with no other point inside its triangle. @param {Point2[]} points @param {number[]} left @param {number} k */\nfunction isEar(points, left, k) {\n if (!convex(points, left, k)) return false\n const n = left.length\n const a = points[left[(k + n - 1) % n]], b = points[left[k]], c = points[left[(k + 1) % n]]\n for (const id of left) {\n const p = points[id]\n if (same(p, a) || same(p, b) || same(p, c)) continue\n if (cross(a, b, p) >= 0 && cross(b, c, p) >= 0 && cross(c, a, p) >= 0) return false\n }\n return true\n}\n","// Geometry generators: plain functions returning a Geometry. Every shape follows the same\n// conventions - +Y up, counter-clockwise front faces, outward normals, glTF UVs (v down).\n\nimport { Geometry } from './Geometry.js'\nimport { area, triangulate } from './triangulate.js'\nimport { checkCount as count, checkLength as size, checkOneOf, describe, fail, resolveOptions as resolve } from '../validate.js'\n\nconst TAU = Math.PI * 2\n\n/** What each generator takes (a number alone sets the first, where that makes sense). */\nexport const GENERATOR_OPTIONS = {\n box: ['size', 'width', 'height', 'depth', 'segments'],\n sphere: ['radius', 'segments', 'rings'],\n plane: ['size', 'width', 'depth', 'segments'],\n cylinder: ['radius', 'radiusTop', 'height', 'segments', 'caps', 'axis'],\n torus: ['radius', 'tube', 'segments', 'tubeSegments'],\n icosphere: ['radius', 'detail'],\n lathe: ['points', 'segments', 'axis'],\n extrude: ['shape', 'holes', 'depth', 'axis'],\n axes: ['size'],\n grid: ['size', 'divisions'],\n}\n\n/**\n * @typedef {object} BoxOptions\n * @property {number} [size] sets width, height and depth together, default 1\n * @property {number} [width] along x, default size\n * @property {number} [height] along y, default size\n * @property {number} [depth] along z, default size\n * @property {number} [segments] subdivisions across each face, default 1\n */\n\n/**\n * @typedef {object} SphereOptions\n * @property {number} [radius] default 1\n * @property {number} [segments] around the Y axis, default 32\n * @property {number} [rings] from pole to pole, default 16\n */\n\n/**\n * @typedef {object} PlaneOptions\n * @property {number} [size] sets width and depth together, default 1\n * @property {number} [width] along x, default size\n * @property {number} [depth] along z, default size\n * @property {number} [segments] subdivisions along each side, default 1\n */\n\n/**\n * @typedef {object} CylinderOptions\n * @property {number} [radius] at the bottom, default 0.5\n * @property {number} [radiusTop] at the top, defaults to `radius`; 0 gives a cone\n * @property {number} [height] along y, default 1\n * @property {number} [segments] around the Y axis, default 32\n * @property {boolean} [caps] close the ends, default true\n * @property {Axis} [axis] the axis it runs along, default 'y'\n */\n\n/**\n * @typedef {object} TorusOptions\n * @property {number} [radius] from the centre to the middle of the tube, default 1\n * @property {number} [tube] radius of the tube, default 0.4\n * @property {number} [segments] around the ring, default 48\n * @property {number} [tubeSegments] around the tube, default 16\n */\n\n/**\n * @typedef {object} IcosphereOptions\n * @property {number} [radius] default 1\n * @property {number} [detail] subdivision level 0-6, default 2; 0 is an icosahedron (20 faces)\n */\n\n/**\n * @typedef {object} LatheOptions\n * @property {ArrayLike<number>[]} points the profile, as [radius, y] pairs from the bottom up - the\n * outside of the surface is on the right as you go up it\n * @property {number} [segments] around the axis, default 32\n * @property {Axis} [axis] the axis it is turned about, default 'y'\n */\n\n/**\n * @typedef {object} ExtrudeOptions\n * @property {ArrayLike<number>[]} shape the outline, as [x, y] pairs, either way round\n * @property {ArrayLike<number>[][]} [holes] outlines cut out of it, each as [x, y] pairs\n * @property {number} [depth] along the axis, default 1\n * @property {Axis} [axis] the axis it is pushed along, default 'z'; the outline is drawn as seen\n * looking back down the axis from its + end, with y up ('y': seen from above, y away from you)\n */\n\n/** @typedef {'x' | 'y' | 'z'} Axis */\n\n/**\n * @typedef {object} AxesOptions\n * @property {number} [size] length of each axis line, default 1\n */\n\n// three.js names people will reach for, mapped to what to use here\nconst SEGMENT_HINT = \"has one 'segments' option, used for every face\"\n\n/**\n * A box centred on the origin. Each face has its own 4+ vertices so normals and UVs are per face;\n * seen from outside, a face's top left has uv (0, 0). Side faces keep +Y up.\n * @example box(2) // 2 x 2 x 2\n * @example box({ width: 2, height: 1, depth: 0.5, segments: 4 })\n * @param {number | BoxOptions} [options] a number sets width, height and depth\n * @returns {Geometry}\n */\nexport function box(options) {\n const owner = 'box()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.box, (n) => ({ size: n }), {\n widthSegments: `box() ${SEGMENT_HINT}`,\n heightSegments: `box() ${SEGMENT_HINT}`,\n depthSegments: `box() ${SEGMENT_HINT}`,\n })\n // size sets all three; width, height and depth override it per axis\n const all = size(owner, 'size', o.size, 1)\n const width = size(owner, 'width', o.width, all)\n const height = size(owner, 'height', o.height, all)\n const depth = size(owner, 'depth', o.depth, all)\n const segments = count(owner, 'segments', o.segments, 1)\n const scale = [width, height, depth]\n const m = new Builder()\n for (const [n, right, up] of BOX_FACES) {\n const start = m.count\n for (let j = 0; j <= segments; j++) {\n const v = j / segments\n for (let i = 0; i <= segments; i++) {\n const u = i / segments\n const p = [0, 1, 2].map((k) => (n[k] * 0.5 + right[k] * (u - 0.5) + up[k] * (0.5 - v)) * scale[k])\n m.vertex(p[0], p[1], p[2], n[0], n[1], n[2], u, v)\n }\n }\n m.grid(start, segments, segments)\n }\n return m.build({ type: 'box', width, height, depth, segments })\n}\n\n// [normal, right (u grows), up (v shrinks)] per face, with right x up = normal so faces wind CCW\nconst BOX_FACES = [\n [[1, 0, 0], [0, 0, -1], [0, 1, 0]],\n [[-1, 0, 0], [0, 0, 1], [0, 1, 0]],\n [[0, 1, 0], [1, 0, 0], [0, 0, -1]],\n [[0, -1, 0], [1, 0, 0], [0, 0, 1]],\n [[0, 0, 1], [1, 0, 0], [0, 1, 0]],\n [[0, 0, -1], [-1, 0, 0], [0, 1, 0]],\n]\n\n/**\n * A UV sphere centred on the origin. u runs once around (with a seam column of repeated vertices\n * so the texture can wrap), v from the north pole (0) to the south pole (1).\n * @example sphere(2)\n * @example sphere({ radius: 1, segments: 64, rings: 32 })\n * @param {number | SphereOptions} [options] a number sets the radius\n * @returns {Geometry}\n */\nexport function sphere(options) {\n const owner = 'sphere()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.sphere, (n) => ({ radius: n }), {\n widthSegments: \"sphere(): use 'segments' for the divisions around the sphere\",\n heightSegments: \"sphere(): use 'rings' for the divisions from pole to pole\",\n })\n const radius = size(owner, 'radius', o.radius, 1)\n const segments = count(owner, 'segments', o.segments, 32, 3)\n const rings = count(owner, 'rings', o.rings, 16, 2)\n const m = new Builder()\n for (let j = 0; j <= rings; j++) {\n const v = j / rings\n const pole = j === 0 || j === rings\n // exact poles, so they sit on the axis and weld in edges()\n const sinT = pole ? 0 : Math.sin(v * Math.PI)\n const cosT = j === 0 ? 1 : j === rings ? -1 : Math.cos(v * Math.PI)\n for (let i = 0; i <= segments; i++) {\n // a pole vertex serves only the triangle to its right, so centre its u over that triangle\n const u = pole && i < segments ? (i + 0.5) / segments : i / segments\n const phi = ((i % segments) / segments) * TAU // the seam column repeats column 0 exactly\n const nx = -Math.cos(phi) * sinT, ny = cosT, nz = Math.sin(phi) * sinT\n m.vertex(nx * radius, ny * radius, nz * radius, nx, ny, nz, u, v)\n }\n }\n m.grid(0, segments, rings, { pinchTop: true, pinchBottom: true })\n return m.build({ type: 'sphere', radius, segments, rings })\n}\n\n/**\n * A flat rectangle in the x-z plane, centred on the origin and facing +Y. Seen from above, the\n * -x, -z corner has uv (0, 0) and the +x, +z corner (1, 1).\n * @example plane(10)\n * @example plane({ width: 4, depth: 2, segments: 8 })\n * @param {number | PlaneOptions} [options] a number sets width and depth\n * @returns {Geometry}\n */\nexport function plane(options) {\n const owner = 'plane()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.plane, (n) => ({ size: n }), {\n height: \"plane() lies in the x-z plane - use 'depth' rather than 'height'\",\n widthSegments: `plane() ${SEGMENT_HINT}`,\n heightSegments: `plane() ${SEGMENT_HINT}`,\n })\n const all = size(owner, 'size', o.size, 1)\n const width = size(owner, 'width', o.width, all)\n const depth = size(owner, 'depth', o.depth, all)\n const segments = count(owner, 'segments', o.segments, 1)\n const m = new Builder()\n for (let j = 0; j <= segments; j++) {\n const v = j / segments\n for (let i = 0; i <= segments; i++) {\n const u = i / segments\n m.vertex((u - 0.5) * width, 0, (v - 0.5) * depth, 0, 1, 0, u, v)\n }\n }\n m.grid(0, segments, segments)\n return m.build({ type: 'plane', width, depth, segments })\n}\n\n/**\n * A cylinder along the Y axis (or `axis`), centred on the origin; `radiusTop: 0` makes a cone. The\n * side and the caps have separate vertices so both get the right normals. u runs around the side\n * from +Z.\n * @example cylinder({ radius: 0.5, height: 2 })\n * @example cylinder({ radius: 1, radiusTop: 0 }) // a cone\n * @example cylinder({ radius: 0.1, height: 3, axis: 'x' }) // an axle lying along x\n * @param {CylinderOptions} [options]\n * @returns {Geometry}\n */\nexport function cylinder(options) {\n const owner = 'cylinder()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.cylinder, null, {\n radiusBottom: \"cylinder(): use 'radius' for the bottom radius\",\n radialSegments: \"cylinder(): use 'segments' for the divisions around the cylinder\",\n openEnded: \"cylinder(): use 'caps: false' for an open tube\",\n })\n const radius = size(owner, 'radius', o.radius, 0.5, true)\n const radiusTop = size(owner, 'radiusTop', o.radiusTop, radius, true)\n if (radius === 0 && radiusTop === 0) fail(owner, \"'radius' and 'radiusTop' can't both be 0\")\n const height = size(owner, 'height', o.height, 1)\n const segments = count(owner, 'segments', o.segments, 32, 3)\n const caps = o.caps ?? true\n if (typeof caps !== 'boolean') fail(owner, `'caps' must be true or false, got ${describe(caps)}`)\n const axis = axisOf(owner, o.axis, 'y')\n\n const m = new Builder()\n // side normals lean up as the side narrows towards the top\n const slope = radius - radiusTop, len = Math.hypot(height, slope)\n const out = height / len, ny = slope / len\n for (let j = 0; j <= 1; j++) {\n const r = j === 0 ? radiusTop : radius\n const y = j === 0 ? height / 2 : -height / 2\n for (let i = 0; i <= segments; i++) {\n // a cone's tip, like a sphere's pole, serves one triangle - centre its u and normal on it\n const u = r === 0 && i < segments ? (i + 0.5) / segments : i / segments\n const phi = r === 0 ? u * TAU : ((i % segments) / segments) * TAU\n const s = Math.sin(phi), c = Math.cos(phi)\n m.vertex(r * s, y, r * c, out * s, ny, out * c, u, j)\n }\n }\n m.grid(0, segments, 1, { pinchTop: radiusTop === 0, pinchBottom: radius === 0 })\n if (caps) {\n if (radiusTop > 0) cap(m, radiusTop, height / 2, 1, segments)\n if (radius > 0) cap(m, radius, -height / 2, -1, segments)\n }\n m.turn('y', axis)\n return m.build({ type: 'cylinder', radius, radiusTop, height, segments, caps, ...(axis !== 'y' && { axis }) })\n}\n\n/**\n * A disc closing one end of a cylinder: a centre vertex plus a ring. UVs map the disc into the\n * unit square the way a box's top and bottom faces are mapped.\n * @param {Builder} m @param {number} radius @param {number} y @param {1 | -1} side +1 top, -1 bottom\n * @param {number} segments\n */\nfunction cap(m, radius, y, side, segments) {\n const centre = m.vertex(0, y, 0, 0, side, 0, 0.5, 0.5)\n for (let i = 0; i < segments; i++) {\n const phi = (i / segments) * TAU, s = Math.sin(phi), c = Math.cos(phi)\n // seen from outside the top cap has -z up and the bottom cap +z up\n m.vertex(radius * s, y, radius * c, 0, side, 0, 0.5 + s / 2, 0.5 + (side * c) / 2)\n }\n for (let i = 0; i < segments; i++) {\n const a = centre + 1 + i, b = centre + 1 + ((i + 1) % segments)\n // the ring turns counter-clockwise seen from +Y, so the bottom cap reverses it\n if (side > 0) m.indices.push(centre, a, b)\n else m.indices.push(centre, b, a)\n }\n}\n\n/**\n * A torus lying in the x-z plane (the ring goes around the Y axis), centred on the origin.\n * u runs around the ring from +Z, v around the tube starting at its outer edge and heading down.\n * @example torus({ radius: 1, tube: 0.25 })\n * @param {TorusOptions} [options]\n * @returns {Geometry}\n */\nexport function torus(options) {\n const owner = 'torus()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.torus, null, {\n tubularSegments: \"torus(): use 'segments' for the divisions around the ring\",\n radialSegments: \"torus(): use 'tubeSegments' for the divisions around the tube\",\n })\n const radius = size(owner, 'radius', o.radius, 1)\n const tube = size(owner, 'tube', o.tube, 0.4)\n const segments = count(owner, 'segments', o.segments, 48, 3)\n const tubeSegments = count(owner, 'tubeSegments', o.tubeSegments, 16, 3)\n const m = new Builder()\n for (let j = 0; j <= tubeSegments; j++) {\n const v = j / tubeSegments\n // negative angle so v heads down the outside first, keeping the winding counter-clockwise\n const theta = -((j % tubeSegments) / tubeSegments) * TAU\n const ct = Math.cos(theta), st = Math.sin(theta)\n for (let i = 0; i <= segments; i++) {\n const u = i / segments\n const phi = ((i % segments) / segments) * TAU\n const dx = Math.sin(phi), dz = Math.cos(phi)\n const nx = ct * dx, ny = st, nz = ct * dz\n m.vertex(radius * dx + tube * nx, tube * ny, radius * dz + tube * nz, nx, ny, nz, u, v)\n }\n }\n m.grid(0, segments, tubeSegments)\n return m.build({ type: 'torus', radius, tube, segments, tubeSegments })\n}\n\n/**\n * A sphere made by subdividing an icosahedron - evenly spread triangles, no poles. Vertices are\n * shared, so it is smooth shaded; it has no UVs (use sphere() for texturing).\n * @example icosphere({ radius: 1, detail: 3 })\n * @param {number | IcosphereOptions} [options] a number sets the radius\n * @returns {Geometry}\n */\nexport function icosphere(options) {\n const owner = 'icosphere()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.icosphere, (n) => ({ radius: n }), {\n subdivisions: \"icosphere(): use 'detail' (0-6) for the subdivision level\",\n })\n const radius = size(owner, 'radius', o.radius, 1)\n const detail = count(owner, 'detail', o.detail, 2, 0, 6)\n\n const t = (1 + Math.sqrt(5)) / 2\n /** @type {number[]} unit-length directions */\n const dirs = []\n const add = (x, y, z) => {\n const l = Math.hypot(x, y, z)\n dirs.push(x / l, y / l, z / l)\n return dirs.length / 3 - 1\n }\n for (const [x, y, z] of [\n [-1, t, 0], [1, t, 0], [-1, -t, 0], [1, -t, 0], [0, -1, t], [0, 1, t],\n [0, -1, -t], [0, 1, -t], [t, 0, -1], [t, 0, 1], [-t, 0, -1], [-t, 0, 1],\n ]) add(x, y, z)\n let faces = [\n 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1,\n ]\n for (let level = 0; level < detail; level++) {\n // each edge's midpoint is made once and shared by the two triangles either side\n /** @type {Map<number, number>} */\n const midpoints = new Map()\n const mid = (a, b) => {\n const key = a < b ? a * 65536 + b : b * 65536 + a\n let m = midpoints.get(key)\n if (m === undefined) {\n m = add(dirs[a * 3] + dirs[b * 3], dirs[a * 3 + 1] + dirs[b * 3 + 1], dirs[a * 3 + 2] + dirs[b * 3 + 2])\n midpoints.set(key, m)\n }\n return m\n }\n const next = []\n for (let f = 0; f < faces.length; f += 3) {\n const a = faces[f], b = faces[f + 1], c = faces[f + 2]\n const ab = mid(a, b), bc = mid(b, c), ca = mid(c, a)\n next.push(a, ab, ca, ab, b, bc, ca, bc, c, ab, bc, ca)\n }\n faces = next\n }\n const g = new Geometry({ positions: dirs.map((d) => d * radius), normals: dirs, indices: faces })\n g.source = { type: 'icosphere', radius, detail }\n return g\n}\n\n/**\n * A profile turned about the Y axis (or `axis`, with y up the profile becoming that axis), as on a\n * lathe: pistons, bottles, bolts, vases, pulleys. Corners sharper\n * than about 30 degrees stay sharp; gentler ones are shaded smooth. A profile that starts or ends\n * on the axis (radius 0) closes over it. u runs around from +Z and v along the profile from its\n * last point to its first - top to bottom, as on cylinder().\n * @example lathe({ points: [[0, 0], [1, 0], [1, 2], [0.6, 2.4], [0, 2.4]] }) // a closed can with a shoulder\n * @example lathe({ points: outline.arc({ radius: 1, from: -Math.PI / 2, to: Math.PI / 2 }), axis: 'x' }) // a ball on an x axle\n * @param {LatheOptions} options\n * @returns {Geometry}\n */\nexport function lathe(options) {\n const owner = 'lathe()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.lathe, null, {\n divisions: \"lathe(): use 'segments' for the divisions around the axis\",\n phiSegments: \"lathe(): use 'segments' for the divisions around the axis\",\n profile: \"lathe(): use 'points' for the profile, as [radius, y] pairs\",\n })\n // a radius a hair off the axis (an arc's end, from cos(pi / 2)) is on it, so the shape closes there\n const points = pairs(owner, 'points', o.points, 2).map(([r, y]) => /** @type {[number, number]} */ ([Math.abs(r) < 1e-9 ? 0 : r, y]))\n if (points.some(([r]) => r < 0)) fail(owner, \"'points' are [radius, y] pairs - a radius can't be below 0\")\n const segments = count(owner, 'segments', o.segments, 32, 3)\n const axis = axisOf(owner, o.axis, 'y')\n\n // each span of the profile, with its outward normal (to the right, going up)\n const spans = []\n for (let k = 0; k + 1 < points.length; k++) {\n const [r0, y0] = points[k], [r1, y1] = points[k + 1]\n const len = Math.hypot(r1 - r0, y1 - y0)\n if (len === 0) continue\n spans.push({ from: points[k], to: points[k + 1], len, normal: [(y1 - y0) / len, -(r1 - r0) / len] })\n }\n if (!spans.length) fail(owner, \"'points' need at least two different points\")\n const total = spans.reduce((t, s) => t + s.len, 0)\n const m = new Builder()\n let along = 0\n spans.forEach((s, k) => {\n const start = smoothed(spans[k - 1]?.normal, s.normal), end = smoothed(spans[k + 1]?.normal, s.normal)\n const first = m.count\n // the far end first, as cylinder() puts its top row first, so the winding faces out\n for (const [[r, y], [nr, ny], v] of [[s.to, end, 1 - (along + s.len) / total], [s.from, start, 1 - along / total]]) {\n for (let i = 0; i <= segments; i++) {\n const phi = ((i % segments) / segments) * TAU, sin = Math.sin(phi), cos = Math.cos(phi)\n m.vertex(r * sin, y, r * cos, nr * sin, ny, nr * cos, i / segments, v)\n }\n }\n m.grid(first, segments, 1, { pinchTop: s.to[0] === 0, pinchBottom: s.from[0] === 0 })\n along += s.len\n })\n m.turn('y', axis)\n return m.build({ type: 'lathe', points: points.map((p) => [...p]), segments, ...(axis !== 'y' && { axis }) })\n}\n\n/**\n * A flat outline pushed out along Z (or `axis`), centred on the origin: the front faces +Z, the\n * back -Z, and the sides follow the outline. With another axis the front faces that axis's + end,\n * the outline drawn as seen from there. Concave outlines and holes are fine. Corners sharper than about 30\n * degrees stay sharp; gentler ones are shaded smooth, so a many-sided circle looks round. On the\n * front and back u, v span the outline's bounds, upright as seen from that side; on the sides u\n * runs round each outline and v from front to back.\n * @example extrude({ shape: [[0, 0], [2, 0], [2, 1], [0, 1]], depth: 0.5 })\n * @example extrude({ shape: outline.rect(2), holes: [outline.circle(0.5)], depth: 0.2 }) // a plate with a hole\n * @example extrude({ shape: outline.gear({ radius: 1, teeth: 40 }), depth: 0.1, axis: 'x' }) // a gear on an x axle\n * @param {ExtrudeOptions} options\n * @returns {Geometry}\n */\nexport function extrude(options) {\n const owner = 'extrude()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.extrude, null, {\n amount: \"extrude(): use 'depth'\",\n points: \"extrude(): use 'shape' for the outline, as [x, y] pairs\",\n outline: \"extrude(): use 'shape' for the outline, as [x, y] pairs\",\n bevelEnabled: \"extrude() has no bevel - round the shape's corners instead\",\n })\n const shape = withoutRepeats(pairs(owner, 'shape', o.shape, 3))\n if (o.holes !== undefined && !Array.isArray(o.holes)) fail(owner, `'holes' must be a list of outlines, got ${describe(o.holes)}`)\n if (typeof o.holes?.[0]?.[0] === 'number') fail(owner, \"'holes' is a list of outlines - for one hole, holes: [outline]\")\n const holes = /** @type {unknown[]} */ (o.holes ?? []).map((h, i) => withoutRepeats(pairs(owner, `holes[${i}]`, h, 3)))\n const depth = size(owner, 'depth', o.depth, 1)\n const axis = axisOf(owner, o.axis, 'z')\n const front = depth / 2\n\n // the outline counter-clockwise and the holes clockwise, so every side faces out of the solid\n const outline = area(shape) < 0 ? [...shape].reverse() : shape\n const cutouts = holes.map((h) => (area(h) > 0 ? [...h].reverse() : h))\n const all = [outline, ...cutouts].flat()\n let x0 = Infinity, x1 = -Infinity, y0 = Infinity, y1 = -Infinity\n for (const [x, y] of all) {\n x0 = Math.min(x0, x)\n x1 = Math.max(x1, x)\n y0 = Math.min(y0, y)\n y1 = Math.max(y1, y)\n }\n const w = x1 - x0 || 1, h = y1 - y0 || 1\n\n const m = new Builder()\n // front and back, from one triangulation\n const tris = triangulate(outline, cutouts)\n for (const [z, nz] of [[front, 1], [-front, -1]]) {\n const start = m.count\n // the back is mapped as seen from behind, as box() maps its back face\n for (const [x, y] of all) m.vertex(x, y, z, 0, 0, nz, nz > 0 ? (x - x0) / w : (x1 - x) / w, (y1 - y) / h)\n for (let t = 0; t < tris.length; t += 3) {\n if (nz > 0) m.indices.push(start + tris[t], start + tris[t + 1], start + tris[t + 2])\n else m.indices.push(start + tris[t], start + tris[t + 2], start + tris[t + 1])\n }\n }\n // the sides: a quad per edge, sharing normals with the next edge across a gentle corner\n for (const ring of [outline, ...cutouts]) {\n const n = ring.length\n const lengths = ring.map(([ax, ay], i) => Math.hypot(ring[(i + 1) % n][0] - ax, ring[(i + 1) % n][1] - ay))\n const normals = ring.map(([ax, ay], i) => {\n const [bx, by] = ring[(i + 1) % n], l = lengths[i] || 1\n return /** @type {[number, number]} */ ([(by - ay) / l, -(bx - ax) / l])\n })\n const perimeter = lengths.reduce((t, l) => t + l, 0) || 1\n let along = 0\n for (let i = 0; i < n; i++) {\n const own = normals[i]\n const [na, nb] = [smoothed(normals[(i + n - 1) % n], own), smoothed(normals[(i + 1) % n], own)]\n const [ax, ay] = ring[i], [bx, by] = ring[(i + 1) % n]\n const u0 = along / perimeter, u1 = (along + lengths[i]) / perimeter\n const a = m.vertex(ax, ay, front, na[0], na[1], 0, u0, 0)\n const b = m.vertex(ax, ay, -front, na[0], na[1], 0, u0, 1)\n const c = m.vertex(bx, by, -front, nb[0], nb[1], 0, u1, 1)\n const d = m.vertex(bx, by, front, nb[0], nb[1], 0, u1, 0)\n m.indices.push(a, b, c, a, c, d)\n along += lengths[i]\n }\n }\n m.turn('z', axis)\n return m.build({ type: 'extrude', shape: shape.map((p) => [...p]), holes: holes.map((hole) => hole.map((p) => [...p])), depth, ...(axis !== 'z' && { axis }) })\n}\n\n// corners turning less than this (about 30 degrees) are shaded smooth\nconst CREASE = Math.cos(Math.PI / 6)\n\n/**\n * A 2D normal where a span meets its neighbour: the two averaged across a gentle corner, its own at\n * a sharp one (or at an end, with no neighbour).\n * @param {number[] | undefined} other @param {number[]} own\n * @returns {number[]}\n */\nfunction smoothed(other, own) {\n if (!other || other[0] * own[0] + other[1] * own[1] < CREASE) return own\n const x = other[0] + own[0], y = other[1] + own[1], l = Math.hypot(x, y) || 1\n return [x / l, y / l]\n}\n\n/**\n * A list of [a, b] number pairs, at least `min` long.\n * @param {string} owner @param {string} name @param {unknown} value @param {number} min\n * @returns {[number, number][]}\n */\nfunction pairs(owner, name, value, min) {\n if (!Array.isArray(value)) fail(owner, `'${name}' must be a list of [x, y] pairs, got ${describe(value)}`)\n const list = /** @type {any[]} */ (value)\n if (list.length < min) fail(owner, `'${name}' needs at least ${min} points, got ${list.length}`)\n return list.map((p, i) => {\n if (!p || typeof p !== 'object' || typeof p.length !== 'number' || p.length < 2) {\n fail(owner, `'${name}' must be a list of [x, y] pairs - point ${i} is ${describe(p)}`)\n }\n const a = p[0], b = p[1]\n if (typeof a !== 'number' || typeof b !== 'number' || !Number.isFinite(a) || !Number.isFinite(b)) {\n fail(owner, `'${name}' point ${i} must be two finite numbers, got ${describe(p)}`)\n }\n return /** @type {[number, number]} */ ([a, b])\n })\n}\n\n/**\n * Line geometry outlining a mesh: one vertex pair per edge, for drawing as Lines. Edges shared by\n * two faces that are flat to each other (within `angle` degrees - 1 unless given) are left out, so a\n * box gives its 12 outline edges rather than its triangle diagonals. A larger angle leaves out the\n * facets of round surfaces too - 30 draws a cylinder's rims but not the lines down its side, as a\n * drawing does. Vertices at exactly the same position are merged first, so meshes with separate\n * vertices per face (box()) still share their edges.\n * @example new Lines({ geometry: edges(box()) })\n * @example new Lines({ geometry: edges(cylinder({ segments: 48 }), { angle: 30 }) }) // just the rims\n * @param {Geometry} geometry triangles, indexed or not\n * @param {{ angle?: number }} [options] how far, in degrees, two faces must turn from each other to make an edge (default 1)\n * @returns {Geometry}\n */\nexport function edges(geometry, options = {}) {\n if (!(geometry instanceof Geometry)) fail('edges()', `expected a Geometry, got ${describe(geometry)}`)\n const { angle = 1 } = resolve('edges()', options, ['angle'], null)\n if (!(angle >= 0 && angle < 180)) fail('edges()', `'angle' is in degrees, 0 to under 180, got ${describe(angle)}`)\n const flat = Math.cos((angle * Math.PI) / 180)\n const p = geometry.positions, index = geometry.indices, n = geometry.vertexCount\n // weld: map each vertex to the first vertex at the same position\n /** @type {Map<string, number>} */\n const seen = new Map()\n const weld = new Uint32Array(n)\n for (let i = 0; i < n; i++) {\n const key = `${p[i * 3]},${p[i * 3 + 1]},${p[i * 3 + 2]}`\n let w = seen.get(key)\n if (w === undefined) seen.set(key, w = i)\n weld[i] = w\n }\n\n /** @type {Map<number, { a: number, b: number, nx: number, ny: number, nz: number, faces: number, crease: boolean }>} */\n const found = new Map()\n const corners = index ? index.length : n\n for (let t = 0; t + 2 < corners; t += 3) {\n const a = weld[index ? index[t] : t], b = weld[index ? index[t + 1] : t + 1], c = weld[index ? index[t + 2] : t + 2]\n const abx = p[b * 3] - p[a * 3], aby = p[b * 3 + 1] - p[a * 3 + 1], abz = p[b * 3 + 2] - p[a * 3 + 2]\n const acx = p[c * 3] - p[a * 3], acy = p[c * 3 + 1] - p[a * 3 + 1], acz = p[c * 3 + 2] - p[a * 3 + 2]\n let nx = aby * acz - abz * acy, ny = abz * acx - abx * acz, nz = abx * acy - aby * acx\n const len = Math.hypot(nx, ny, nz)\n if (len === 0) continue // degenerate: no faces to compare, nothing to outline\n nx /= len\n ny /= len\n nz /= len\n for (const [v0, v1] of [[a, b], [b, c], [c, a]]) {\n const lo = Math.min(v0, v1), hi = Math.max(v0, v1)\n const key = lo * n + hi\n const e = found.get(key)\n if (!e) found.set(key, { a: lo, b: hi, nx, ny, nz, faces: 1, crease: false })\n else {\n e.faces++\n if (e.nx * nx + e.ny * ny + e.nz * nz < flat) e.crease = true\n }\n }\n }\n\n // keep open edges and creases; compact to just the vertices they use\n /** @type {Map<number, number>} */\n const remap = new Map()\n /** @type {number[]} */\n const positions = []\n /** @type {number[]} */\n const indices = []\n const use = (v) => {\n let i = remap.get(v)\n if (i === undefined) {\n remap.set(v, i = positions.length / 3)\n positions.push(p[v * 3], p[v * 3 + 1], p[v * 3 + 2])\n }\n return i\n }\n for (const e of found.values()) {\n if (e.faces === 1 || e.crease) indices.push(use(e.a), use(e.b))\n }\n return new Geometry({ positions, indices })\n}\n\n/**\n * Line geometry for the three axes: from the origin along +X (red), +Y (green) and +Z (blue).\n * Draw with Lines and `vertexColors: true`.\n * @example new Lines({ geometry: axes(2), material: new LineMaterial({ vertexColors: true }) })\n * @param {number | AxesOptions} [options] a number sets the size\n * @returns {Geometry}\n */\nexport function axes(options) {\n const owner = 'axes()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.axes, (n) => ({ size: n }))\n const s = size(owner, 'size', o.size, 1)\n const g = new Geometry({\n positions: [0, 0, 0, s, 0, 0, 0, 0, 0, 0, s, 0, 0, 0, 0, 0, 0, s],\n colors: [1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1],\n })\n g.source = { type: 'axes', size: s }\n return g\n}\n\n/**\n * A square grid of lines in the x-z plane, centred on the origin - draw it with Lines. (A plane's\n * edges() would only give its outline, since edges() drops lines between flat faces.)\n * @example new Lines({ geometry: grid({ size: 10, divisions: 10 }), material: { color: '#999' } })\n * @param {number | { size?: number, divisions?: number }} [options] a number sets the size\n * @returns {Geometry}\n */\nexport function grid(options) {\n const owner = 'grid()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.grid, (n) => ({ size: n }), {\n segments: \"grid() uses 'divisions' for the number of squares along each side\",\n })\n const s = size(owner, 'size', o.size, 10)\n const divisions = count(owner, 'divisions', o.divisions, 10)\n const half = s / 2\n /** @type {number[]} */\n const positions = []\n for (let i = 0; i <= divisions; i++) {\n const p = -half + (s * i) / divisions\n positions.push(p, 0, -half, p, 0, half, -half, 0, p, half, 0, p)\n }\n const g = new Geometry({ positions })\n g.source = { type: 'grid', size: s, divisions }\n return g\n}\n\n// Collects vertex data for the analytic shapes, which supply their own normals and UVs.\nclass Builder {\n /** @type {number[]} */ positions = []\n /** @type {number[]} */ normals = []\n /** @type {number[]} */ uvs = []\n /** @type {number[]} */ indices = []\n\n get count() {\n return this.positions.length / 3\n }\n\n /**\n * @param {number} x @param {number} y @param {number} z\n * @param {number} nx @param {number} ny @param {number} nz\n * @param {number} u @param {number} v\n * @returns {number} the new vertex's index\n */\n vertex(x, y, z, nx, ny, nz, u, v) {\n this.positions.push(x, y, z)\n this.normals.push(nx, ny, nz)\n this.uvs.push(u, v)\n return this.count - 1\n }\n\n /**\n * Triangulate a grid of (cols + 1) x (rows + 1) vertices added row by row from `start`: top row\n * first, u growing along each row, as seen from the front. Each cell becomes two triangles\n * wound counter-clockwise from the front. A pinched row is a single point (a pole or a cone's\n * tip), where one triangle per cell is enough and the other would have no area.\n * @param {number} start @param {number} cols @param {number} rows\n * @param {{ pinchTop?: boolean, pinchBottom?: boolean }} [pinch]\n */\n grid(start, cols, rows, { pinchTop = false, pinchBottom = false } = {}) {\n const stride = cols + 1\n for (let j = 0; j < rows; j++) {\n for (let i = 0; i < cols; i++) {\n const a = start + j * stride + i // top left\n const b = a + stride // bottom left\n const c = b + 1 // bottom right\n const d = a + 1 // top right\n if (!(pinchBottom && j === rows - 1)) this.indices.push(a, b, c)\n if (!(pinchTop && j === 0)) this.indices.push(a, c, d)\n }\n }\n }\n\n /**\n * Lay what has been built along another axis: a quarter turn - never a mirror, so faces still\n * face out. From y (turned shapes): x is reached by turning about z, z by turning about x. From z\n * (pushed outlines): x by turning about y, so the outline is seen from +x, and y by turning about\n * x, so it is seen from above.\n * @param {'y' | 'z'} from @param {Axis} to\n */\n turn(from, to) {\n if (from === to) return\n const map = TURNS[from][to]\n for (const list of [this.positions, this.normals]) {\n for (let i = 0; i < list.length; i += 3) {\n const [x, y, z] = map(list[i], list[i + 1], list[i + 2])\n list[i] = x\n list[i + 1] = y\n list[i + 2] = z\n }\n }\n }\n\n /** @param {{ type: string } & Record<string, unknown>} source @returns {Geometry} */\n build(source) {\n const { positions, normals, uvs, indices } = this\n const g = new Geometry({ positions, normals, uvs, indices })\n g.source = source\n return g\n }\n}\n\n/** @type {Record<string, Record<string, (x: number, y: number, z: number) => number[]>>} */\nconst TURNS = {\n y: { x: (x, y, z) => [y, -x, z], z: (x, y, z) => [x, -z, y] },\n z: { x: (x, y, z) => [z, y, -x], y: (x, y, z) => [x, z, -y] },\n}\n\n/**\n * The axis option, or the shape's own when it's missing.\n * @param {string} owner @param {unknown} value @param {Axis} fallback\n * @returns {Axis}\n */\nfunction axisOf(owner, value, fallback) {\n return value === undefined ? fallback : checkOneOf(owner, 'axis', /** @type {Axis} */ (value), ['x', 'y', 'z'])\n}\n\n/**\n * An outline without repeated points. Two in a row - or a last point back at the first, as joined arcs\n * and a rounded rect's straight-less ends give - make a side of no length, which has no direction to\n * face and would crease the smooth sides either side of it (lathe() skips them the same way).\n * @template {ArrayLike<number>} P\n * @param {P[]} points\n * @returns {P[]}\n */\nfunction withoutRepeats(points) {\n const kept = points.filter((p, i) => {\n const q = points[(i + points.length - 1) % points.length]\n return p[0] !== q[0] || p[1] !== q[1]\n })\n return kept.length >= 3 ? kept : points\n}\n","// Flat outlines for extrude() and lathe(): plain lists of [x, y] points, counter-clockwise, so they\n// can be spread into one another to make a shape - a rod's eyes joined by its sides, a cam's base\n// circle and nose. Angles are radians, anticlockwise from +x.\nimport { checkCount, checkLength, checkNumber, describe, fail, resolveOptions } from '../validate.js'\n\n/** @typedef {[number, number]} Point2 */\n\nconst TAU = Math.PI * 2\n\n/** What each outline takes (a number alone sets the first, where that makes sense). */\nexport const OUTLINE_OPTIONS = {\n circle: ['radius', 'segments', 'center'],\n rect: ['size', 'width', 'height', 'radius', 'segments', 'center'],\n polygon: ['radius', 'sides', 'angle', 'center'],\n arc: ['radius', 'from', 'to', 'segments', 'center'],\n gear: ['radius', 'teeth', 'depth', 'center'],\n}\n\nconst HINTS = {\n r: \"use 'radius'\",\n x: \"use center: [x, y]\",\n y: \"use center: [x, y]\",\n centre: \"use 'center'\",\n startAngle: \"use 'from' (radians)\",\n endAngle: \"use 'to' (radians)\",\n cornerRadius: \"use 'radius' for the corners' rounding\",\n n: \"use 'sides' (polygon) or 'segments'\",\n}\n\n/**\n * @typedef {object} CircleOptions\n * @property {number} [radius] default 1\n * @property {number} [segments] points round it, default 32\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * A circle's outline - a hole for an axle, a bolt, a bore.\n * @example extrude({ shape: outline.circle(1), holes: [outline.circle(0.4)], depth: 0.2 }) // a washer\n * @param {number | CircleOptions} [options] a number sets the radius\n * @returns {Point2[]}\n */\nfunction circle(options) {\n const owner = 'outline.circle()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.circle, (n) => ({ radius: n }))\n const radius = checkLength(owner, 'radius', o.radius, 1)\n const segments = checkCount(owner, 'segments', o.segments, 32, 3)\n const [cx, cy] = point(owner, 'center', o.center)\n return Array.from({ length: segments }, (_, i) => {\n const a = i / segments * TAU\n return /** @type {Point2} */ ([cx + Math.cos(a) * radius, cy + Math.sin(a) * radius])\n })\n}\n\n/**\n * @typedef {object} RectOptions\n * @property {number} [size] sets width and height together, default 1\n * @property {number} [width] along x, default size\n * @property {number} [height] along y, default size\n * @property {number} [radius] rounds the corners, default 0 (square)\n * @property {number} [segments] points round each rounded corner, default 8\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * A rectangle's outline, square-cornered or rounded - a plate, a bracket, a slot.\n * @example outline.rect({ width: 4, height: 1.3, radius: 0.2 })\n * @param {number | RectOptions} [options] a number sets width and height\n * @returns {Point2[]}\n */\nfunction rect(options) {\n const owner = 'outline.rect()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.rect, (n) => ({ size: n }))\n const all = checkLength(owner, 'size', o.size, 1)\n const width = checkLength(owner, 'width', o.width, all), height = checkLength(owner, 'height', o.height, all)\n const radius = o.radius === undefined ? 0 : checkNumber(owner, 'radius', o.radius)\n if (radius < 0 || radius > Math.min(width, height) / 2) fail(owner, `'radius' must be from 0 to half the shorter side (${Math.min(width, height) / 2}), got ${radius}`)\n const segments = checkCount(owner, 'segments', o.segments, 8, 1)\n const [cx, cy] = point(owner, 'center', o.center)\n const w = width / 2, h = height / 2\n if (radius === 0) return [[cx - w, cy - h], [cx + w, cy - h], [cx + w, cy + h], [cx - w, cy + h]]\n /** @type {Point2[]} */\n const out = []\n // each corner's arc, anticlockwise from the bottom right\n for (const [x, y, start] of [[w - radius, -h + radius, -Math.PI / 2], [w - radius, h - radius, 0], [-w + radius, h - radius, Math.PI / 2], [-w + radius, -h + radius, Math.PI]]) {\n for (let i = 0; i <= segments; i++) {\n const a = start + i / segments * Math.PI / 2\n out.push([cx + x + Math.cos(a) * radius, cy + y + Math.sin(a) * radius])\n }\n }\n return out\n}\n\n/**\n * @typedef {object} PolygonOptions\n * @property {number} [radius] to the corners, default 1\n * @property {number} [sides] default 6\n * @property {number} [angle] turns it, radians; default 0, a corner on +x\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * A regular polygon's outline - a hex nut, a triangle, an octagon.\n * @example extrude({ shape: outline.polygon({ radius: 0.2, sides: 6 }), holes: [outline.circle(0.1)], depth: 0.1 }) // a nut\n * @param {number | PolygonOptions} [options] a number sets the radius\n * @returns {Point2[]}\n */\nfunction polygon(options) {\n const owner = 'outline.polygon()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.polygon, (n) => ({ radius: n }))\n const radius = checkLength(owner, 'radius', o.radius, 1)\n const sides = checkCount(owner, 'sides', o.sides, 6, 3)\n const angle = o.angle === undefined ? 0 : checkNumber(owner, 'angle', o.angle)\n const [cx, cy] = point(owner, 'center', o.center)\n return Array.from({ length: sides }, (_, i) => {\n const a = angle + i / sides * TAU\n return /** @type {Point2} */ ([cx + Math.cos(a) * radius, cy + Math.sin(a) * radius])\n })\n}\n\n/**\n * @typedef {object} ArcOptions\n * @property {number} [radius] default 1\n * @property {number} [from] start angle, radians anticlockwise from +x; default 0\n * @property {number} [to] end angle; default a whole turn on from `from`. Below `from`, the arc runs clockwise\n * @property {number} [segments] pieces along it, default enough for 32 a turn\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * Points along an arc, both ends included - to join with others into an outline: a connecting\n * rod's two eyes, a crank web's pin end and counterweight.\n * @example extrude({ shape: [...outline.arc({ radius: 0.3, from: 0, to: Math.PI }), ...outline.arc({ radius: 0.6, from: Math.PI, to: 2 * Math.PI, center: [0, -0.5] })] })\n * @param {ArcOptions} [options]\n * @returns {Point2[]}\n */\nfunction arc(options) {\n const owner = 'outline.arc()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.arc, null)\n const radius = checkLength(owner, 'radius', o.radius, 1)\n const from = o.from === undefined ? 0 : checkNumber(owner, 'from', o.from)\n const to = o.to === undefined ? from + TAU : checkNumber(owner, 'to', o.to)\n if (to === from) fail(owner, \"'from' and 'to' are the same angle - there's no arc between them\")\n const segments = checkCount(owner, 'segments', o.segments, Math.max(1, Math.ceil(Math.abs(to - from) / TAU * 32)), 1)\n const [cx, cy] = point(owner, 'center', o.center)\n return Array.from({ length: segments + 1 }, (_, i) => {\n const a = from + (to - from) * i / segments\n return /** @type {Point2} */ ([cx + Math.cos(a) * radius, cy + Math.sin(a) * radius])\n })\n}\n\n/**\n * @typedef {object} GearOptions\n * @property {number} [radius] to the tips of the teeth, default 1\n * @property {number} [teeth] default 24\n * @property {number} [depth] how far the teeth stand out, default a tooth's width\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * A gear's toothed outline: straight-sided teeth round a root circle - flywheels, sprockets, cogs.\n * @example extrude({ shape: outline.gear({ radius: 1, teeth: 72, depth: 0.05 }), holes: [outline.circle(0.1)], depth: 0.1 })\n * @param {number | GearOptions} [options] a number sets the radius\n * @returns {Point2[]}\n */\nfunction gear(options) {\n const owner = 'outline.gear()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.gear, (n) => ({ radius: n }))\n const radius = checkLength(owner, 'radius', o.radius, 1)\n const teeth = checkCount(owner, 'teeth', o.teeth, 24, 3)\n const depth = checkLength(owner, 'depth', o.depth, Math.min(radius / 2, radius * Math.PI / teeth))\n if (depth >= radius) fail(owner, `'depth' must be less than the radius (${radius}), got ${depth}`)\n const [cx, cy] = point(owner, 'center', o.center)\n const root = radius - depth, step = TAU / teeth\n /** @type {Point2[]} */\n const out = []\n // a tooth: up its leading flank, across the tip, down its trailing flank, then along the root\n for (let i = 0; i < teeth; i++) {\n for (const [f, r] of [[0, root], [0.12, radius], [0.38, radius], [0.5, root]]) {\n const a = (i + f) * step\n out.push([cx + Math.cos(a) * r, cy + Math.sin(a) * r])\n }\n }\n return out\n}\n\n/**\n * Flat outlines for extrude() and lathe(), each a list of [x, y] points. Spread several into one\n * list to build a shape, or pass them as holes.\n */\nexport const outline = { circle, rect, polygon, arc, gear }\n\n// --- checking\n\n/** The shapes' options, with their hints. @param {string} owner @param {unknown} options @param {string[]} keys @param {((n: number) => object) | null} fromNumber */\nconst resolve = (owner, options, keys, fromNumber) => resolveOptions(owner, options, keys, fromNumber, HINTS)\n\n/** @param {string} owner @param {string} name @param {unknown} value @returns {Point2} */\nfunction point(owner, name, value) {\n if (value === undefined) return [0, 0]\n const p = /** @type {any} */ (value)\n if (!p || typeof p !== 'object' || typeof p[0] !== 'number' || typeof p[1] !== 'number' || !Number.isFinite(p[0]) || !Number.isFinite(p[1])) {\n fail(owner, `'${name}' must be [x, y], got ${describe(value)}`)\n }\n return [p[0], p[1]]\n}\n","// Converts phoria v1 model data ({x,y,z} points plus n-gon polygons) into a Geometry - the\n// migration path for hand-made models.\n\nimport { Geometry } from './Geometry.js'\nimport { checkOptions, describe, fail } from '../validate.js'\n\nconst OWNER = 'fromPolygons()'\n\n/**\n * @typedef {object} PolygonData\n * @property {number[]} vertices indices into `points`, 3 or more, counter-clockwise seen from the front\n * @property {number[]} [uvs] a u, v pair per vertex, in the same order\n */\n\n/**\n * @typedef {object} PolygonsOptions\n * @property {Array<{ x: number, y: number, z: number } | number[]>} points\n * @property {PolygonData[]} polygons\n * @property {unknown} [edges] accepted and ignored, so a whole v1 model can be passed; use edges() for wireframes\n * @property {boolean} [smooth] share normals across faces at shared points - curved surfaces look round\n * rather than faceted (default false; only without uvs, where the points stay shared)\n */\n\n/**\n * Make a Geometry from v1-style data. Each polygon is triangulated as a fan from its first vertex\n * (fine for the convex polygons v1 models use) and given flat normals - the faceted v1 look - unless\n * `smooth` is set.\n * Without UVs the points stay shared; if any polygon has UVs every corner gets its own vertex so\n * UVs can differ per face. Other v1 polygon fields (color, texture...) are ignored.\n * @example fromPolygons({ points: [{ x: 0, y: 0, z: 0 }, ...], polygons: [{ vertices: [0, 1, 2, 3] }] })\n * @param {PolygonsOptions} options\n * @returns {Geometry}\n */\nexport function fromPolygons(options) {\n checkOptions(OWNER, options, ['points', 'polygons', 'edges', 'smooth'])\n const { points, polygons } = options ?? /** @type {PolygonsOptions} */ ({})\n if (!Array.isArray(points)) fail(OWNER, `'points' must be an array of { x, y, z } or [x, y, z], got ${describe(points)}`)\n if (!Array.isArray(polygons)) fail(OWNER, `'polygons' must be an array of { vertices: [...] }, got ${describe(polygons)}`)\n\n const xyz = points.map((pt, i) => {\n const c = Array.isArray(pt) ? pt : pt && typeof pt === 'object' ? [pt.x, pt.y, pt.z] : null\n if (!c || c.length !== 3 || !c.every(Number.isFinite)) {\n fail(OWNER, `point ${i} must be { x, y, z } or [x, y, z] numbers, got ${describe(pt)}`)\n }\n return c\n })\n\n polygons.forEach((polygon, p) => {\n const vs = polygon?.vertices\n if (!Array.isArray(vs) || vs.length < 3) fail(OWNER, `polygon ${p} needs 'vertices' with 3 or more point indices, got ${describe(vs)}`)\n for (const v of vs) {\n if (!Number.isInteger(v) || v < 0 || v >= xyz.length) {\n fail(OWNER, `polygon ${p} refers to point ${describe(v)} but there are only ${xyz.length} points`)\n }\n }\n const uvs = polygon.uvs\n if (uvs !== undefined && (!Array.isArray(uvs) || uvs.length !== vs.length * 2 || !uvs.every(Number.isFinite))) {\n fail(OWNER, `polygon ${p} 'uvs' must be ${vs.length * 2} numbers (a u, v pair per vertex), got ${describe(uvs)}`)\n }\n })\n\n // fan triangulation: (0, 1, 2), (0, 2, 3)... keeps each polygon's winding\n /** @type {Array<[number, number]>} [polygon, corner] for each triangle corner */\n const corners = []\n polygons.forEach(({ vertices }, p) => {\n for (let k = 1; k + 1 < vertices.length; k++) corners.push([p, 0], [p, k], [p, k + 1])\n })\n\n let geometry\n const withUvs = polygons.some((p) => p.uvs)\n if (withUvs) {\n const positions = [], uvs = []\n for (const [p, k] of corners) {\n const { vertices, uvs: pu } = polygons[p]\n positions.push(...xyz[vertices[k]])\n uvs.push(pu ? pu[k * 2] : 0, pu ? pu[k * 2 + 1] : 0)\n }\n geometry = new Geometry({ positions, uvs })\n } else {\n geometry = new Geometry({\n positions: xyz.flat(),\n indices: corners.map(([p, k]) => polygons[p].vertices[k]),\n })\n }\n return geometry.computeNormals({ flat: !(options.smooth && !withUvs) })\n}\n","// Curves: a smooth path through points, or an ellipse - to draw as a line, a dashed line or a\n// tube, and to move things along (phoria2/motion). Positions along a curve go by distance, so\n// t = 0.5 is half way along it, however unevenly its points are spaced.\n\nimport { Geometry } from './Geometry.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { setAxisAngle } from '../math/quat.js'\nimport { checkCount, checkNumber, checkOneOf, checkOptions, describe, fail } from '../validate.js'\n\n/** @import { Vec3Input } from '../types.js' */\n\n/**\n * @typedef {object} CurveOptions\n * @property {boolean} [closed] join the last point back to the first, default false\n * @property {number} [tension] how tightly the curve hugs its points, 0 (round) to 1 (straight lines), default 0\n */\n\n/**\n * @typedef {object} EllipseOptions\n * @property {'xz' | 'xy' | 'yz'} [plane] the plane it lies in, default 'xz' (flat, like an orbit seen from above)\n * @property {number} [radius] sets both radii, default 1\n * @property {number} [radiusX] across x, default radius (planes 'xz' and 'xy')\n * @property {number} [radiusY] across y, default radius (planes 'xy' and 'yz')\n * @property {number} [radiusZ] across z, default radius (planes 'xz' and 'yz')\n * @property {Vec3Input} [center] default [0, 0, 0]\n * @property {number} [tilt] radians about the plane's first axis (x, or y for 'yz'), default 0\n */\n\n/**\n * @typedef {object} LineOptions\n * @property {number} [segments] straight pieces along the whole curve, default by length (about 20 a unit, 400 at most)\n * @property {[number, number]} [dash] [on, off] lengths in the curve's units, for a dashed line\n */\n\n/**\n * @typedef {object} TubeOptions\n * @property {number} [radius] default 0.1\n * @property {number} [segments] rings along the curve, default by length (about 20 a unit, 400 at most)\n * @property {number} [sides] around the tube, default 8\n */\n\n/** What curve(), curve.line(), curve.tube() and ellipse() take, and hints for names people reach for instead. */\nexport const CURVE_OPTIONS = ['closed', 'tension']\nexport const CURVE_HINTS = { loop: \"use 'closed: true'\", smooth: \"the curve is always smooth - 'tension' (0-1) sets how tight\" }\nexport const LINE_OPTIONS = ['segments', 'dash']\nexport const LINE_HINTS = { dashed: \"use 'dash: [on, off]' - lengths in the curve's units\" }\nexport const TUBE_OPTIONS = ['radius', 'segments', 'sides']\nexport const TUBE_HINTS = { tubularSegments: \"use 'segments'\", radialSegments: \"use 'sides'\" }\n// an ellipse takes the two radii of its plane as well: radiusX and radiusZ in 'xz'\nexport const ELLIPSE_OPTIONS = ['plane', 'radius', 'center', 'tilt']\n\nconst SAMPLES = 48 // per span between control points, for measuring length\n\n/** A smooth curve. Make one with curve(points) or ellipse(options). */\nexport class Curve {\n /** @type {Vec3[]} */ #points\n #closed\n #tension\n /** cumulative lengths at even steps of the raw parameter, for going by distance */\n /** @type {Float64Array} */ #lengths\n\n /**\n * @param {Vec3Input[]} points two or more\n * @param {CurveOptions} [options]\n */\n constructor(points, options = {}) {\n if (!Array.isArray(points) || points.length < 2) fail('curve()', `needs an array of two or more points, got ${describe(points)}`)\n checkOptions('curve()', options, CURVE_OPTIONS, CURVE_HINTS)\n this.#points = points.map((p) => Vec3.fromInput(p, 'curve()'))\n this.#closed = !!options.closed\n this.#tension = options.tension === undefined ? 0 : checkNumber('curve()', 'tension', options.tension)\n const n = this.#spans() * SAMPLES\n this.#lengths = new Float64Array(n + 1)\n let prev = this.#raw(0)\n for (let i = 1; i <= n; i++) {\n const p = this.#raw(i / n)\n this.#lengths[i] = this.#lengths[i - 1] + p.distanceTo(prev)\n prev = p\n }\n }\n\n /** Its length, in the units of its points. */\n get length() {\n return this.#lengths[this.#lengths.length - 1]\n }\n\n get closed() {\n return this.#closed\n }\n\n /**\n * The point t of the way along it by distance: 0 is the start, 1 the end.\n * @param {number} t @param {Vec3} [out]\n * @returns {Vec3}\n */\n at(t, out = new Vec3()) {\n return this.#raw(this.#toRaw(t), out)\n }\n\n /**\n * The direction it runs in at t, as a unit vector.\n * @param {number} t @param {Vec3} [out]\n * @returns {Vec3}\n */\n tangentAt(t, out = new Vec3()) {\n const u = this.#toRaw(t), e = 1e-4\n const a = this.#raw(Math.max(0, u - e)), b = this.#raw(Math.min(1, u + e))\n return out.copy(b.sub(a)).normalize()\n }\n\n /**\n * Evenly spaced points along it, for your own geometry.\n * @param {number} count @returns {Vec3[]}\n */\n points(count) {\n const n = checkCount('curve.points()', 'count', count ?? null, 2, 2)\n // a closed curve's last point would repeat its first\n const last = this.#closed ? n : n - 1\n return Array.from({ length: n }, (_, i) => this.at(i / last))\n }\n\n /**\n * Line geometry along it, for a Lines node - solid, or dashed with dash: [on, off].\n * Its pieces run in order from the start, so geometry.drawCount can draw just the first part.\n *\n * scene.add(new Lines({ geometry: path.line({ dash: [0.3, 0.15] }), material: { color: 'orange', width: 2 } }))\n * @param {LineOptions} [options]\n * @returns {Geometry}\n */\n line(options = {}) {\n checkOptions('curve.line()', options, LINE_OPTIONS, LINE_HINTS)\n const segments = this.#segments('curve.line()', options.segments)\n const step = this.length / segments\n /** @type {number[]} */\n const positions = []\n const piece = (from, to) => {\n // a run along the curve, cut into pieces about a step long\n const n = Math.max(1, Math.ceil((to - from) / step - 1e-9))\n let prev = this.at(from / this.length)\n for (let i = 1; i <= n; i++) {\n const p = this.at((from + (to - from) * i / n) / this.length)\n positions.push(prev[0], prev[1], prev[2], p[0], p[1], p[2])\n prev = p\n }\n }\n if (options.dash === undefined) piece(0, this.length)\n else {\n const dash = options.dash\n if (!Array.isArray(dash) || dash.length !== 2 || !dash.every((d) => d > 0)) fail('curve.line()', `'dash' is [on, off], two lengths above 0, got ${describe(dash)}`)\n for (let d = 0; d < this.length; d += dash[0] + dash[1]) piece(d, Math.min(this.length, d + dash[0]))\n }\n return new Geometry({ positions })\n }\n\n /**\n * Tube geometry along it, for a Mesh - a pipe of the curve's shape.\n * @param {TubeOptions} [options]\n * @returns {Geometry}\n */\n tube(options = {}) {\n checkOptions('curve.tube()', options, TUBE_OPTIONS, TUBE_HINTS)\n const radius = options.radius === undefined ? 0.1 : checkNumber('curve.tube()', 'radius', options.radius)\n const sides = checkCount('curve.tube()', 'sides', options.sides, 8, 3)\n const segments = this.#segments('curve.tube()', options.segments)\n const rings = this.#closed ? segments : segments + 1\n /** @type {number[]} */\n const positions = []\n /** @type {number[]} */\n const indices = []\n // each ring's frame is carried along from the last one, so the tube doesn't twist\n let tangent = this.tangentAt(0)\n let normal = new Vec3(...(Math.abs(tangent[1]) < 0.9 ? [0, 1, 0] : [1, 0, 0])).cross(tangent).normalize()\n for (let i = 0; i < rings; i++) {\n const t = i / segments\n const next = this.tangentAt(t)\n // turn the normal by however the tangent turned\n normal = next.clone().cross(normal.clone().cross(next)).normalize()\n tangent = next\n const binormal = tangent.clone().cross(normal)\n const c = this.at(t)\n for (let s = 0; s < sides; s++) {\n const a = s / sides * Math.PI * 2, x = Math.cos(a) * radius, y = Math.sin(a) * radius\n positions.push(c[0] + normal[0] * x + binormal[0] * y, c[1] + normal[1] * x + binormal[1] * y, c[2] + normal[2] * x + binormal[2] * y)\n }\n }\n for (let i = 0; i < segments; i++) {\n const j = (i + 1) % rings\n for (let s = 0; s < sides; s++) {\n const a = i * sides + s, b = j * sides + s, c = j * sides + (s + 1) % sides, d = i * sides + (s + 1) % sides\n indices.push(a, d, c, a, c, b)\n }\n }\n return new Geometry({ positions, indices })\n }\n\n #spans() {\n return this.#closed ? this.#points.length : this.#points.length - 1\n }\n\n /** @param {string} owner @param {number | undefined} segments */\n #segments(owner, segments) {\n if (segments !== undefined) return checkCount(owner, 'segments', segments, 1)\n return Math.min(400, Math.max(8, Math.round(this.length * 20)))\n }\n\n /** The raw curve parameter (even per span) for a distance fraction t. @param {number} t */\n #toRaw(t) {\n const total = this.length, target = Math.min(1, Math.max(0, t)) * total\n const lengths = this.#lengths\n let lo = 0, hi = lengths.length - 1\n while (hi - lo > 1) {\n const mid = (lo + hi) >> 1\n if (lengths[mid] < target) lo = mid\n else hi = mid\n }\n const span = lengths[hi] - lengths[lo]\n return (lo + (span > 0 ? (target - lengths[lo]) / span : 0)) / (lengths.length - 1)\n }\n\n /** A point at raw parameter u (0-1), on a cardinal spline through the points. @param {number} u @param {Vec3} [out] */\n #raw(u, out = new Vec3()) {\n const pts = this.#points, n = pts.length, spans = this.#spans()\n const x = Math.min(1, Math.max(0, u)) * spans\n const i = Math.min(spans - 1, Math.floor(x)), f = x - i\n const get = (k) => (this.#closed ? pts[((k % n) + n) % n] : pts[Math.min(n - 1, Math.max(0, k))])\n const p0 = get(i - 1), p1 = get(i), p2 = get(i + 1), p3 = get(i + 2)\n // centripetal: the tangents weigh each neighbour by the square root of its distance, so\n // unevenly spaced points don't make the curve overshoot into loops or cusps. Evenly spaced,\n // it's the plain Catmull-Rom curve\n const d0 = Math.sqrt(p1.distanceTo(p0)), d1 = Math.sqrt(p2.distanceTo(p1)) || 1e-9, d2 = Math.sqrt(p3.distanceTo(p2))\n const s = 1 - this.#tension\n const f2 = f * f, f3 = f2 * f\n const h1 = 2 * f3 - 3 * f2 + 1, h2 = -2 * f3 + 3 * f2, h3 = f3 - 2 * f2 + f, h4 = f3 - f2\n for (let k = 0; k < 3; k++) {\n const chord = (p2[k] - p1[k]) / d1\n // at an end, where the neighbour is the point itself, the tangent runs along the chord (at half\n // strength, as the plain curve has it)\n const t1 = d0 > 1e-9 ? (p1[k] - p0[k]) / d0 - (p2[k] - p0[k]) / (d0 + d1) + chord : chord / 2\n const t2 = d2 > 1e-9 ? chord - (p3[k] - p1[k]) / (d1 + d2) + (p3[k] - p2[k]) / d2 : chord / 2\n const m1 = s * t1 * d1, m2 = s * t2 * d1\n out[k] = h1 * p1[k] + h2 * p2[k] + h3 * m1 + h4 * m2\n }\n return out\n }\n}\n\n/**\n * A smooth curve through points - for paths, routes and trajectories.\n *\n * const route = curve([[0, 0, 0], [2, 3, 0], [6, 2, 1]])\n * route.at(0.5) // half way along, by distance\n * @param {Vec3Input[]} points\n * @param {CurveOptions} [options]\n * @returns {Curve}\n */\nexport function curve(points, options) {\n return new Curve(points, options)\n}\n\n/**\n * A closed ellipse - for orbits. It lies flat in x-z unless plane says otherwise, and starts on its\n * first axis, running toward its second: from +x toward +z in 'xz'.\n *\n * const orbit = ellipse({ radiusX: 4, radiusZ: 3, center: [8, 0, 0] })\n * const face = ellipse({ plane: 'xy', radiusX: 3, radiusY: 2 }) // facing the camera\n * @param {EllipseOptions} [options]\n * @returns {Curve}\n */\nexport function ellipse(options = {}) {\n const plane = options.plane === undefined ? 'xz' : checkOneOf('ellipse()', 'plane', options.plane, ['xz', 'xy', 'yz'])\n const [u, v] = [...plane].map((a) => 'xyz'.indexOf(a))\n const name = (a) => `radius${'XYZ'[a]}`\n const off = name(3 - u - v)\n checkOptions('ellipse()', options, [...ELLIPSE_OPTIONS, name(u), name(v)], {\n [off]: `an ellipse in '${plane}' has '${name(u)}' and '${name(v)}' - set plane for another`,\n })\n const r = options.radius === undefined ? 1 : checkNumber('ellipse()', 'radius', options.radius)\n const radius = (a) => (options[name(a)] === undefined ? r : checkNumber('ellipse()', name(a), options[name(a)]))\n const ru = radius(u), rv = radius(v)\n const c = Vec3.fromInput(options.center ?? [0, 0, 0], 'ellipse()')\n const tilt = options.tilt === undefined ? 0 : checkNumber('ellipse()', 'tilt', options.tilt)\n const axis = [0, 0, 0]\n axis[u] = 1\n const turn = setAxisAngle(new Float32Array(4), axis, tilt)\n // enough points that the spline through them is a true ellipse to well under a pixel\n const n = 64\n const points = Array.from({ length: n }, (_, i) => {\n const a = i / n * Math.PI * 2, p = new Vec3()\n p[u] = Math.cos(a) * ru\n p[v] = Math.sin(a) * rv\n return p.applyQuaternion(turn).add(c)\n })\n return new Curve(points, { closed: true })\n}\n","// Node types added from outside the core (a chart from phoria2/charts), so create() can build their\n// descriptions. Kept apart from describe.js so registering a type doesn't pull in every node class.\n\n/** @type {Map<string, new (options: any) => any>} */\nconst types = new Map()\n\n/**\n * Let create() build descriptions of this node class, by its static `type`. Sub-path modules\n * (phoria2/charts) register theirs when imported. A class with options of its own adds them to its\n * parent's, so the node options still work:\n *\n * class Beacon extends Group {\n * static type = 'beacon'\n * static get OPTIONS() { return [...super.OPTIONS, 'blink'] }\n * }\n * registerType(Beacon)\n * @param {(new (options: any) => any) & { type: string }} Class\n */\nexport function registerType(Class) {\n types.set(Class.type, Class)\n}\n\n/** @internal */\nexport function registeredTypes() {\n return types\n}\n","// Plain-data descriptions: create() builds any node from { type: 'mesh', ... }, the inverse of\n// node.toJSON(). Every constructor's options are its description, plus the type. This is the one\n// place descriptions are accepted, so apps that never use them don't carry this module (or every\n// geometry generator).\nimport { describe, didYouMean, fail, checkOneOf } from './validate.js'\nimport { Geometry } from './geometry/Geometry.js'\nimport * as generators from './geometry/generators.js'\nimport { Node, Group } from './scene/Node.js'\nimport { Scene } from './scene/Scene.js'\nimport { InstancedMesh, Label, Lines, Mesh, Points } from './scene/drawables.js'\nimport { OrthographicCamera, PerspectiveCamera } from './scene/cameras.js'\nimport { AmbientLight, DirectionalLight, HemisphereLight, PointLight, SpotLight } from './scene/lights.js'\nimport { registeredTypes } from './registry.js'\n\n/** Generator types usable in geometry descriptions: { type: 'box', size: 2 }. */\nexport const GEOMETRY_TYPES = ['box', 'sphere', 'plane', 'cylinder', 'torus', 'icosphere', 'lathe', 'extrude', 'axes', 'grid']\n\n// Built on first use, not at module load, so these modules can import each other in any order.\n/** @type {Map<string, new (options: any) => Node> | null} */\nlet types = null\nconst typeMap = () => {\n types ??= new Map([\n Node, Group, Scene, Mesh, InstancedMesh, Points, Lines, Label, PerspectiveCamera, OrthographicCamera,\n AmbientLight, HemisphereLight, DirectionalLight, PointLight, SpotLight,\n ].map((Class) => [Class.type, Class]))\n // plus types registered by sub-paths, such as 'chart' from phoria2/charts\n for (const [type, Class] of registeredTypes()) types.set(type, Class)\n return types\n}\n\n// The names people coming from three.js will type\nconst THREE_TYPES = {\n Mesh: 'mesh', Group: 'group', Object3D: 'node', Points: 'points', LineSegments: 'lines', Line: 'lines',\n InstancedMesh: 'instanced-mesh', PerspectiveCamera: 'perspective-camera', OrthographicCamera: 'orthographic-camera',\n AmbientLight: 'ambient-light', HemisphereLight: 'hemisphere-light', DirectionalLight: 'directional-light',\n PointLight: 'point-light', SpotLight: 'spot-light', Scene: 'scene', light: 'directional-light', camera: 'perspective-camera',\n}\n// sub-path types that aren't registered until their module is imported\nconst SUBPATH_TYPES = { chart: \"import { chart } from 'phoria2/charts' first, which registers 'chart'\", emitter: \"'emitter' descriptions aren't supported yet - use new Emitter() from 'phoria2/particles'\" }\n\n// geometry names people reach for, and three.js geometry classes\nconst GEOMETRY_ALIASES = {\n cube: 'box', ball: 'sphere', globe: 'sphere', quad: 'plane', tube: 'cylinder', ring: 'torus', donut: 'torus',\n BoxGeometry: 'box', SphereGeometry: 'sphere', PlaneGeometry: 'plane', CylinderGeometry: 'cylinder',\n TorusGeometry: 'torus', IcosahedronGeometry: 'icosphere', GridHelper: 'grid', AxesHelper: 'axes',\n LatheGeometry: 'lathe', ExtrudeGeometry: 'extrude', ShapeGeometry: 'extrude',\n}\n\n/** @param {string} type @returns {string | null} a hint when a material or geometry is described as a node */\nfunction notANode(type) {\n if (/Material$/.test(type)) return `materials aren't nodes - give a mesh material: { color, roughness, metalness, ... }`\n const geometry = GEOMETRY_ALIASES[type]\n if (geometry) return `geometry isn't a node - give a mesh geometry: { type: '${geometry}', ... }`\n return null\n}\n\n/**\n * Build a node (and its children) from a description: its constructor options plus a `type`, as\n * produced by node.toJSON(). Children and geometry may be descriptions too.\n *\n * scene.add(create({ type: 'mesh', geometry: { type: 'box', size: 2 }, material: { color: 'orange' } }))\n *\n * Textures named by url start loading straight away; `await scene.ready` waits for them.\n * @template {Node} [T=Node]\n * @param {{ type: string } & Record<string, any>} description\n * @returns {T}\n */\nexport function create(description) {\n if (description instanceof Node) return /** @type {T} */ (description)\n if (!description || typeof description !== 'object' || Array.isArray(description)) {\n fail('create()', `expected a description such as { type: 'mesh', ... }, got ${describe(description)}`)\n }\n const { type, ...options } = description\n if (typeof type !== 'string') {\n fail('create()', `a description needs a 'type': one of ${[...typeMap().keys()].join(', ')}`)\n }\n const Class = typeMap().get(type)\n if (!Class) {\n const three = THREE_TYPES[type], misplaced = notANode(type) ?? SUBPATH_TYPES[type]\n fail('create()', `unknown type '${type}' - ${three ? `use '${three}'` : misplaced ?? `expected one of ${[...typeMap().keys()].join(', ')}${didYouMean(type, typeMap().keys())}`}`)\n }\n if (Array.isArray(options.children)) options.children = options.children.map((c) => create(c))\n if (options.geometry && !(options.geometry instanceof Geometry) && typeof options.geometry === 'object' && 'type' in options.geometry) {\n options.geometry = createGeometry(options.geometry, `create({ type: '${type}' })`)\n }\n return /** @type {T} */ (new Class(options))\n}\n\n/**\n * A Geometry from a generator description such as { type: 'sphere', radius: 2 }.\n * @param {{ type: string } & Record<string, unknown>} description\n * @param {string} [owner]\n * @returns {Geometry}\n */\nexport function createGeometry(description, owner = 'createGeometry()') {\n const { type, ...options } = description\n const alias = GEOMETRY_ALIASES[type]\n if (alias) fail(owner, `geometry type '${type}' - use '${alias}'`)\n checkOneOf(owner, 'geometry.type', type, GEOMETRY_TYPES)\n const make = /** @type {(o: any) => Geometry} */ (generators[type])\n return make(Object.keys(options).length ? options : undefined)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core.js","names":["create","identity","invert","multiply","cross","distance","normalize","vec3.add","vec3.subtract","vec3.scale","vec3.normalize","vec3.negate","vec3.lerp","vec3.cross","vec3.dot","vec3.length","vec3.distance","vec3.transformMat4","vec3.transformQuat","mat4.identity","mat4.multiply","mat4.invert","mat4.fromRotationTranslationScale","mat4.lookAt","mat4.create","mat4.ortho","mat4.perspective","mat4.multiply","OPTIONS","OPTIONS","DEFAULTS","HINTS","OPTIONS","HINTS","UP","quat.fromEulerXYZ","quat.fromMat3","mat3.fromMat4","quat.normalize","quat.invert","instanceLabels","ids","nextId","OPTIONS","HINTS","quat.normalize","quat.fromMat3","mat3.fromMat4","mat4.perspective","mat4.ortho","instanceWorld","mat4.invert","mat4.multiply","mat3.normalFromMat4","outline","OPTIONS","HINTS","mat4.multiply","mat3.normalFromMat4","mat4.determinant","HINTS","TAU","resolve","size","count","types","generators","__defProp","__exportAll","target","name","all","no_symbols","EPSILON","create$1","identity$1","out","invert$1","a00","a","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b06","b07","b08","b09","b10","b11","det","determinant","b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","multiply$1","c","b","perspective","f","fovy","aspect","far","nf","near","lookAt","ex","eye","ey","ez","center","z0","z1","z2","len","x0","up","x1","x2","y0","y1","y2","fromRotationTranslationScale","x","q","y","z","w","xx","xy","xz","yy","yz","zz","wx","wy","wz","sx","s","sy","sz","v","ortho","lr","left","right","bt","bottom","top","targetTo","add","subtract","scale","dot","cross$1","ax","ay","az","bx","by","bz","length","distance$1","normalize$1","transformMat4","m","transformQuat","qx","qy","qz","qw","uvx","uvy","uvz","uuvx","uuvy","uuvz","w2","lerp","t","negate","PhoriaError","fail","owner","message","distance","d","i","j","cost","suggest","lower","list","candidates","prefixed","best","bestScore","score","didYouMean","checkOptions","options","keys","known","describe","key","hints","checkNumber","checkRange","n","above","min","max","checkOneOf","allowed","hint","warned","warnOnce","seen","resolveOptions","o","fromNumber","checkLength","value","fallback","zero","checkCount","Vec3","toArray","epsilon","Mat4","quaternion","position","Box3","p","positions","box","SHADOW_MAP_SIZE","fitShadow","boxes","casters","normalized","direction","view","corners","px","py","pz","across","area","receivers","margin","depthMargin","steps","h","tx","size","ty","dz","projection","viewProjection","SPOT_ATLAS_SIZE","fitSpotShadow","at","depths","caster","range","fov","angle","POINT_SHADOW_SIZE","CUBE_FACES","fitPointShadow","dx","dy","CSS_COLORS","hex","pair","toLinear","toSRGB","clamp01","NUMBER","FUNC","HELP","PARSED","PARSED_MAX","Color","input","#setHex","#setString","arr","g","r","#parse","named","fn","aUnit","bUnit","cUnit","channel","unit","sat","light","hue","CLIP_OPTIONS","CLIP_HINTS","Clip","json","worldPlane","clip","node","l","nx","ny","nz","c0","c1","c2","ox","oy","oz","clipOwner","Euler","#x","#y","#z","e","m11","m12","m13","m22","m23","m32","m33","setAxisAngle","rad","axis","multiply","aw","bw","normalize","invert","inv","slerp","cosom","s0","s1","omega","sinom","fromMat3","trace","root","k","fromEulerXYZ","c3","s2","s3","Quat","OPTIONS$5","POINT_ARRAYS","Geometry","toFloat32","#normals","#autoNormals","#bounds","#changed","flat","#unweld","normals","triangles","#index","abx","aby","abz","acx","acy","acz","#onDispose","idx","expand","src","values","count","OPTIONS$4","DEFAULTS$1","HINTS$5","CHANGES_KEPT","Texture","#colorSpace","#colorSpaceSet","isVideo","VIDEO","loaded","#load","#image","#follow","video","frame","last","running","tick","start","changed","region","width","height","#changes","first","version","regions","current","url","response","parseHDR","img","image","resolve","reject","loadTexture","MAPS","LINEAR_MAPS","FLAGS","NUMBERS","COLORS","DEFAULTS","OPTIONS$3","HOOKS","HELPERS","RESERVED","HINTS$4","Material","#colors","bool","#shader","shaderHooks","maps","u","#maps","slot","#transparent","parts","copy","desc","keepTextures","hooks","part","uniforms","own","uniformValue","bounds","resolveGeometry","type","resolveMaterial","identity","normalFromMat4","fromMat4","NODE_OPTIONS","NODE_HINTS","NO_HANDLERS","UP$1","tmpMat","tmpMat3","Node","#position","#scale","#rotation","#quaternion","Class","#setHighlight","#clip","#setOutline","child","#highlight","#outline","#parent","#children","more","nodes","toNode","#detach","found","predicate","#addUpdate","#handlers","event","#listeners","set","dt","offset","toward","dir","world","parentRot","normalizedRotation","#updateAncestors","#updateSelf","camera","deep","setPoint","inParentSpace","parent","Group","LABEL_PLACES","PLACEMENT_OPTIONS","LABEL_HINTS","INSTANCE_LABEL_HINTS","placement","minScale","instanceLabels$1","one","byRow","style","DRAWABLE_OPTIONS","DRAWABLE_HINTS","Drawable","#geometry","#material","index","padForHooks","Mesh","INSTANCE_OPTIONS","scratch","SCRATCH_COLOR","scratchMatrix","hiddenInstance","InstancedMesh","inst","#checkIndex","#setColor","color","pad","local","cx","cy","cz","im","hx","hy","hz","Points","ARROWS","Lines","Label","material","LIGHT_LIMITS","collect","planes","frustumPlanes","scene","punctual","directional","capped","visit","outline","item","drawItem","blended","solids","instanceLabels","project","addLight","kind","items","capOf","sun","spots","points","fit","sphereInFrustum","receiving","instances","geometry","worldMatrix","cuts","off","ids$1","nextId$1","instanceLabelSet","labels","layer","yScale","id","instanced","data","row","text","toScreen","ndc","depth","rows","r0","r1","r2","r3","radius","NullRenderer","GAP","EDGE","CELL","NEW_OVERLAP","KEEP_OVERLAP","placeBox","edge","viewWidth","place","stackColumns","side","column","groups","group","gap","wants","shift","total","alignColumns","widest","leaderEnd","rule","layoutLabels","order","states","grid","cells","shared","blocked","other","SVG","DIM_OPACITY","LabelLayer","canvas","pointer","#ensureRoot","stats","#elements","overlays","#overlays","#root","#mount","rect","#place","active","label","#entry","entry","#leave","hidden","state","interactive","el","minWidth","textAlign","#leader","now","cs","end","#ensureLines","opacity","line","#lines","svg","#over","#byElement","className","#listen","entryOf","OPTIONS$2","HINTS$3","LIMIT","MAX_FLING","checkSettings","OrbitControl","element","down","#down","move","#move","#up","wheel","#wheel","menu","click","#dragged","#pointerHandlers","#removePointer","#removeListeners","pitch","#orthographic","yaw","dYaw","dPitch","cam","factor","before","#halfHeight","worldPerPixel","#pointers","#velocity","keep","still","#pinchDistance","#pressed","#lastMove","#spread","#panning","spread","elapsed","cap","UP","tmp","tmp3","aimAt","CAMERA_OPTIONS","CAMERA_HINTS","Camera","#target","PerspectiveCamera","OrthographicCamera","DIRECTIONS","CAMERA_PRESETS","ALIASES","cameraPreset","presetDirection","alias","LOW","fitPoints","padding","wide","ahead","axes","lo","hi","mid","centerOf","half","tanV","tanH","u0","u1","v0","v1","du","dv","framingScale","designed","ratio","EASES","edge1","edge2","pvec","tvec","qvec","Ray","origin","along","d2","t0","t1","normal","point","cullBack","closest","dd","denom","LEAF","cache","bvhOf","hit","bvh","build","corner","tri","maxNodes","used","grow","alloc","stack","cx0","cy0","cz0","cx1","cy1","cz1","partition","pivot","walk","ix","iy","iz","enter","worth","test","inverse","instanceWorld$1","localPlane","cutBy","Raycaster","hits","targets","#visit","cut","#mesh","skip","skipInstance","i0","i1","#points","mesh","bestT","bestFace","i2","normalMatrix","P","uv","datum","instance","w0","limit","distanceSq","instanceWorld","outline$1","inside","into","yi","yj","pickArea","shape","within","face","pos","centre","ids","nextId","usesTime","idOf","ChangeWatch","#time","time","#count","#strings","#camera","#scene","#previousCount","#previousStrings","#values","#previous","grown","previous","#push","#pushAll","bg","#texture","env","fog","#node","shown","#drawable","#label","#light","texture","FOG_OPTIONS","FOG_HINTS","Fog","linear","Scene","#setBackground","#setEnvironment","#fog","#background","#environment","runHandlers","waits","ran","children","LIGHT_OPTIONS","LIGHT_HINTS","Light","#color","AmbientLight","HemisphereLight","rest","sky","ground","#ground","AimedLight","#direction","DirectionalLight","#setShadowBounds","#shadowBounds","PointLight","rangeOf","SpotLight","ATTRIBUTES","CLIP","FOG","MAP_SAMPLERS","SAMPLING","CLIP_ONLY_FRAGMENT","COMMON","EQUIRECT","FULLSCREEN_VERTEX","TONE_MAP","MESH_VERTEX","MESH_FRAGMENT","POINTS_VERTEX","POINTS_FRAGMENT","LINES_VERTEX","LINES_FRAGMENT","SOURCES","HOOK_HELPERS","HOOK_SOURCE_NUMBERS","shaderSource","header","defines","vs","fs","splice","source","resume","failed","recent","glslType","ownUniforms","hookFor","types","signature","hook","clash","passDefines","setHookUniforms","program","hookFailed","names","lines","log","where","HOOK_NAMES","Programs","gl","#parallel","#cache","#start","sources","#finish","#empty","shader","shaders","numbered","setters","info","loc","sampler","setterFor","UPLOAD_UNIT","MOST_REGIONS","GRID","layoutOf","withNormals","withTangents","tangentsOf","e1x","e1y","e1z","e2x","e2y","e2z","du1","dv1","du2","dv2","tz","UV_MATRIX","uvMatrix","LINE_CORNERS","SPRITE_LAYOUT","SPRITE_STRIDE","Resources","#aniso","ext","#mark","#triangles","same","layout","#refill","#free","#watch","vao","buffers","attribute","buffer","location","divisor","attributes","matrixBuffer","colorBuffer","indexType","elements","segments","ends","colors","interleavedPair","second","chains","#cornerBuffer","#whiteTexture","#textures","#freeTexture","float","internal","sizeOf","byCell","wrap","nearest","aniso","#anisotropic","users","#usedBy","#sprites","sorting","modelView","backToFront","sizes","opacities","angles","#white","#corners","GLContext","isShared","released","lost","restored","user","needed","#passesLoading","Passes","#watchingCompiles","check","#pickerLoading","Picker","#bloomLoading","Bloom","lose","OPTIONS$1","BLOOM","BLOOM_OPTIONS","BLOOM_HINTS","HINTS$2","bloomSettings","settings","TONE_MAPPING","NO_SHADOWS","MAP_DEFINES","MAP_SLOTS","MAP_UNIFORMS","CLIP_MASK","CAP_SQUARE","CAP_NODE","WebGLRenderer","#bloom","#gpu","#copy","pixelRatio","gpu","#wait","wait","passes","#shadows","bloom","#gatherLights","#draw","#cap","picker","ambient","dirDirection","dirColor","shadowTile","cone","dirCount","punctualCount","pointShadowIndex","addColor","#lightDefines","#studio","#lights","mode","shadows","#defines","shadow","programs","hl","ior","sc","si","bound","transparent","arrows","round","#modelView","#normalMatrix","masks","#capItem","#capMaterials","hasColors","define","hasUvs2","OPTIONS","DEBUG_ALL","DEBUG_OPTIONS","CORNERS","FRAMING_OPTIONS","HINTS$1","EVENT_HINTS","HIGHLIGHT_AMOUNT","FOCUS_COLOR","OWN_CONTEXTS","GPU_PICKING","ownContexts","View","resolveCanvas","#ownCanvas","#autoFrame","#autoFrameFrom","cameraPlace","context","#ownContext","#pickPending","#setMotion","#pixelRatio","#explicitPixelRatio","orbit","#orbitPointer","#loadKeyboard","#labels","labelHandlers","#labelPointer","#keep","#designed","#schedule","old","#flight","#height","#width","#applied","#motion","#systemReduced","#debug","debugOptions","#debugDraw","#debugLoading","#disposed","DebugDraw","#description","#keyboard","#gaveRole","#hovered","#onFrame","#running","#lastTime","#dirty","#updateControls","#render","#fly","waiting","samePlace","#addAutoLights","#highlightFor","#occlude","debug","started","#drawnAt","#frameMs","#labelStats","#tooltip","#loadTooltip","#pointer","#keyFocus","#needsHover","cw","ch","#keepFraming","towards","duration","from","placeOf","#fit","setPlace","method","#drawnPoints","d0","d1","way","turnBetween","setTarget","drawnPoints","#gpuFrame","#exact","work","raycaster","indexed","#viewProjection","content","#tooltipContent","#tooltipClass","#tooltipLoading","Tooltip","#tooltipFor","Keyboard","handlersAbove","snapshot","notes","drawn","onScreen","explain","#rafId","#cleanup","#onScreen","#tick","#updateHover","#debugHovers","#setHovered","#keyAt","#labelHover","#dragging","#hoverBusy","request","nearestAbove","#clickable","was","whole","halfHeight","testing","press","#press","#drag","#moveDrag","leave","#endDrag","pressedAt","drag","resize","motion","follow","visible","plane","#noted","hemi","#autoSky","#autoSun","FIT_DETAIL","cos","checkBool","expected","triangulate","ring","placed","holes","hole","maxX","bridge","M","edges","bestD","crosses","around","cross","d3","d4","isEar","convex","generators_exports","GENERATOR_OPTIONS","cylinder","extrude","icosphere","lathe","sphere","torus","TAU$1","SEGMENT_HINT","Builder","BOX_FACES","rings","pole","sinT","cosT","phi","radiusTop","caps","axisOf","slope","tube","tubeSegments","theta","ct","st","detail","dirs","faces","level","midpoints","next","ab","bc","ca","pairs","spans","smoothed","nr","sin","withoutRepeats","front","cutouts","tris","lengths","perimeter","na","nb","CREASE","weld","remap","indices","use","divisions","stride","cols","pinchBottom","pinchTop","to","map","TURNS","kept","TAU","OUTLINE_OPTIONS","HINTS","circle","polygon","sides","arc","gear","teeth","step","OWNER","fromPolygons","polygons","xyz","pt","uvs","vertices","withUvs","pu","CURVE_OPTIONS","CURVE_HINTS","LINE_OPTIONS","LINE_HINTS","TUBE_OPTIONS","TUBE_HINTS","ELLIPSE_OPTIONS","SAMPLES","Curve","#closed","#tension","#spans","#lengths","prev","#raw","#toRaw","#segments","piece","dash","tangent","binormal","span","pts","get","p0","p1","p2","p3","f2","f3","h1","h2","h3","h4","chord","t2","m1","m2","curve","ellipse","ru","rv","tilt","turn","types$1","registerType","registeredTypes","GEOMETRY_TYPES","typeMap","THREE_TYPES","SUBPATH_TYPES","GEOMETRY_ALIASES","notANode","create","description","three","misplaced","createGeometry","make"],"sources":["../src/math/mat4.js","../src/math/vec3.js","../src/validate.js","../src/value/Vec3.js","../src/value/Mat4.js","../src/value/Box3.js","../src/shadow.js","../src/value/cssColors.js","../src/value/Color.js","../src/clip.js","../src/value/Euler.js","../src/math/quat.js","../src/value/Quat.js","../src/geometry/Geometry.js","../src/material/Texture.js","../src/material/Material.js","../src/resolve.js","../src/math/mat3.js","../src/scene/Node.js","../src/scene/drawables.js","../src/frame.js","../src/labelLayout.js","../src/labels.js","../src/OrbitControl.js","../src/scene/cameras.js","../src/presets.js","../src/ease.js","../src/value/Ray.js","../src/geometry/bvh.js","../src/Raycaster.js","../src/area.js","../src/watch.js","../src/fog.js","../src/scene/Scene.js","../src/scene/lights.js","../src/webgl/hooks.js","../src/webgl/programs.js","../src/webgl/resources.js","../src/webgl/context.js","../src/webgl/WebGLRenderer.js","../src/View.js","../src/geometry/triangulate.js","../src/geometry/generators.js","../src/geometry/outline.js","../src/geometry/fromPolygons.js","../src/geometry/Curve.js","../src/registry.js","../src/describe.js"],"sourcesContent":["// 4x4 matrices as column-major Float32Array(16), the layout WebGL expects. Signatures follow\n// gl-matrix: results are written to `out`, which is also returned. Operations such as\n// translate(out, a, v) post-multiply - out = a * T(v) - so chained calls apply in object space.\n\n/** @typedef {Float32Array | number[]} Mat4Like */\n/** @typedef {Float32Array | number[]} Vec3Like */\n\nconst EPSILON = 0.000001\n\n/** @returns {Float32Array} identity */\nexport function create() {\n return identity(new Float32Array(16))\n}\n\n/** @template {Mat4Like} T @param {T} out @returns {T} */\nexport function identity(out) {\n out.fill(0)\n out[0] = out[5] = out[10] = out[15] = 1\n return out\n}\n\n/** @template {Mat4Like} T @param {T} out @param {Mat4Like} a @returns {T} */\nexport function transpose(out, a) {\n if (out === a) {\n const a01 = a[1], a02 = a[2], a03 = a[3], a12 = a[6], a13 = a[7], a23 = a[11]\n out[1] = a[4]; out[2] = a[8]; out[3] = a[12]\n out[4] = a01; out[6] = a[9]; out[7] = a[13]\n out[8] = a02; out[9] = a12; out[11] = a[14]\n out[12] = a03; out[13] = a13; out[14] = a23\n return out\n }\n for (let c = 0; c < 4; c++) {\n for (let r = 0; r < 4; r++) out[c * 4 + r] = a[r * 4 + c]\n }\n return out\n}\n\n/** @template {Mat4Like} T @param {T} out @param {Mat4Like} a @returns {T | null} null if not invertible */\nexport function invert(out, a) {\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]\n\n const b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10\n const b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11\n const b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12\n const b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30\n const b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31\n const b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32\n\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06\n if (!det) return null\n det = 1 / det\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det\n return out\n}\n\n/** @param {Mat4Like} a @returns {number} */\nexport function determinant(a) {\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]\n const b0 = a00 * a11 - a01 * a10, b1 = a00 * a12 - a02 * a10\n const b2 = a01 * a12 - a02 * a11, b3 = a20 * a31 - a21 * a30\n const b4 = a20 * a32 - a22 * a30, b5 = a21 * a32 - a22 * a31\n const b6 = a00 * b5 - a01 * b4 + a02 * b3\n const b7 = a10 * b5 - a11 * b4 + a12 * b3\n const b8 = a20 * b2 - a21 * b1 + a22 * b0\n const b9 = a30 * b2 - a31 * b1 + a32 * b0\n return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9\n}\n\n/** out = a * b @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {Mat4Like} b @returns {T} */\nexport function multiply(out, a, b) {\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]\n // one column of b at a time, so out may alias a or b\n for (let c = 0; c < 16; c += 4) {\n const b0 = b[c], b1 = b[c + 1], b2 = b[c + 2], b3 = b[c + 3]\n out[c] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30\n out[c + 1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31\n out[c + 2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32\n out[c + 3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33\n }\n return out\n}\n\nexport const mul = multiply\n\n/** out = a * T(v) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {Vec3Like} v @returns {T} */\nexport function translate(out, a, v) {\n const x = v[0], y = v[1], z = v[2]\n if (out !== a) for (let i = 0; i < 12; i++) out[i] = a[i]\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]\n return out\n}\n\n/** out = a * S(v) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {Vec3Like} v @returns {T} */\nexport function scale(out, a, v) {\n for (let i = 0; i < 4; i++) {\n out[i] = a[i] * v[0]\n out[i + 4] = a[i + 4] * v[1]\n out[i + 8] = a[i + 8] * v[2]\n out[i + 12] = a[i + 12]\n }\n return out\n}\n\n/** out = a * R(axis, rad); returns null for a zero-length axis @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {number} rad @param {Vec3Like} axis @returns {T | null} */\nexport function rotate(out, a, rad, axis) {\n let x = axis[0], y = axis[1], z = axis[2]\n let len = Math.hypot(x, y, z)\n if (len < EPSILON) return null\n len = 1 / len\n x *= len\n y *= len\n z *= len\n const s = Math.sin(rad), c = Math.cos(rad), t = 1 - c\n\n // rotation matrix\n const b00 = x * x * t + c, b01 = y * x * t + z * s, b02 = z * x * t - y * s\n const b10 = x * y * t - z * s, b11 = y * y * t + c, b12 = z * y * t + x * s\n const b20 = x * z * t + y * s, b21 = y * z * t - x * s, b22 = z * z * t + c\n\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n out[0] = a00 * b00 + a10 * b01 + a20 * b02\n out[1] = a01 * b00 + a11 * b01 + a21 * b02\n out[2] = a02 * b00 + a12 * b01 + a22 * b02\n out[3] = a03 * b00 + a13 * b01 + a23 * b02\n out[4] = a00 * b10 + a10 * b11 + a20 * b12\n out[5] = a01 * b10 + a11 * b11 + a21 * b12\n out[6] = a02 * b10 + a12 * b11 + a22 * b12\n out[7] = a03 * b10 + a13 * b11 + a23 * b12\n out[8] = a00 * b20 + a10 * b21 + a20 * b22\n out[9] = a01 * b20 + a11 * b21 + a21 * b22\n out[10] = a02 * b20 + a12 * b21 + a22 * b22\n out[11] = a03 * b20 + a13 * b21 + a23 * b22\n if (out !== a) for (let i = 12; i < 16; i++) out[i] = a[i]\n return out\n}\n\n// Rotating about a principal axis mixes two columns of `a`: col i and col j.\nfunction rotateColumns(out, a, rad, i, j, sign) {\n const s = Math.sin(rad) * sign, c = Math.cos(rad)\n if (out !== a) for (let k = 0; k < 16; k++) out[k] = a[k]\n for (let k = 0; k < 4; k++) {\n const ai = a[i + k], aj = a[j + k]\n out[i + k] = ai * c + aj * s\n out[j + k] = aj * c - ai * s\n }\n return out\n}\n\n/** out = a * Rx(rad) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {number} rad @returns {T} */\nexport const rotateX = (out, a, rad) => rotateColumns(out, a, rad, 4, 8, 1)\n/** out = a * Ry(rad) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {number} rad @returns {T} */\nexport const rotateY = (out, a, rad) => rotateColumns(out, a, rad, 0, 8, -1)\n/** out = a * Rz(rad) @template {Mat4Like} T @param {T} out @param {Mat4Like} a @param {number} rad @returns {T} */\nexport const rotateZ = (out, a, rad) => rotateColumns(out, a, rad, 0, 4, 1)\n\n/** Rotation matrix from a quaternion [x, y, z, w]. @template {Mat4Like} T @param {T} out @param {Float32Array | number[]} q @returns {T} */\nexport function fromQuat(out, q) {\n const x = q[0], y = q[1], z = q[2], w = q[3]\n const x2 = x + x, y2 = y + y, z2 = z + z\n const xx = x * x2, yx = y * x2, yy = y * y2\n const zx = z * x2, zy = z * y2, zz = z * z2\n const wx = w * x2, wy = w * y2, wz = w * z2\n out[0] = 1 - yy - zz; out[1] = yx + wz; out[2] = zx - wy; out[3] = 0\n out[4] = yx - wz; out[5] = 1 - xx - zz; out[6] = zy + wx; out[7] = 0\n out[8] = zx + wy; out[9] = zy - wx; out[10] = 1 - xx - yy; out[11] = 0\n out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1\n return out\n}\n\n// Perspective projection with a -1..1 clip-space depth range (OpenGL/WebGL). `far` may be\n// Infinity. A negative fovy flips the image vertically.\n/** @template {Mat4Like} T @param {T} out @param {number} fovy radians @param {number} aspect @param {number} near @param {number} far @returns {T} */\nexport function perspective(out, fovy, aspect, near, far) {\n const f = 1 / Math.tan(fovy / 2)\n out.fill(0)\n out[0] = f / aspect\n out[5] = f\n out[11] = -1\n if (far != null && far !== Infinity) {\n const nf = 1 / (near - far)\n out[10] = (far + near) * nf\n out[14] = 2 * far * near * nf\n } else {\n out[10] = -1\n out[14] = -2 * near\n }\n return out\n}\n\n// View matrix for an eye looking at a centre point. Returns identity when eye and centre match.\n/** @template {Mat4Like} T @param {T} out @param {Vec3Like} eye @param {Vec3Like} center @param {Vec3Like} up @returns {T} */\nexport function lookAt(out, eye, center, up) {\n const ex = eye[0], ey = eye[1], ez = eye[2]\n if (Math.abs(ex - center[0]) < EPSILON && Math.abs(ey - center[1]) < EPSILON && Math.abs(ez - center[2]) < EPSILON) {\n return identity(out)\n }\n // z axis points from the centre back to the eye\n let z0 = ex - center[0], z1 = ey - center[1], z2 = ez - center[2]\n let len = 1 / Math.hypot(z0, z1, z2)\n z0 *= len; z1 *= len; z2 *= len\n\n let x0 = up[1] * z2 - up[2] * z1\n let x1 = up[2] * z0 - up[0] * z2\n let x2 = up[0] * z1 - up[1] * z0\n len = Math.hypot(x0, x1, x2)\n if (!len) {\n x0 = x1 = x2 = 0\n } else {\n len = 1 / len\n x0 *= len; x1 *= len; x2 *= len\n }\n\n let y0 = z1 * x2 - z2 * x1\n let y1 = z2 * x0 - z0 * x2\n let y2 = z0 * x1 - z1 * x0\n len = Math.hypot(y0, y1, y2)\n if (!len) {\n y0 = y1 = y2 = 0\n } else {\n len = 1 / len\n y0 *= len; y1 *= len; y2 *= len\n }\n\n out[0] = x0; out[1] = y0; out[2] = z0; out[3] = 0\n out[4] = x1; out[5] = y1; out[6] = z1; out[7] = 0\n out[8] = x2; out[9] = y2; out[10] = z2; out[11] = 0\n out[12] = -(x0 * ex + x1 * ey + x2 * ez)\n out[13] = -(y0 * ex + y1 * ey + y2 * ez)\n out[14] = -(z0 * ex + z1 * ey + z2 * ez)\n out[15] = 1\n return out\n}\n\n/** Compose translation, rotation and scale: T * R * S. @template {Mat4Like} T @param {T} out @param {Float32Array | number[]} q @param {Vec3Like} v @param {Vec3Like} s @returns {T} */\nexport function fromRotationTranslationScale(out, q, v, s) {\n const x = q[0], y = q[1], z = q[2], w = q[3]\n const x2 = x + x, y2 = y + y, z2 = z + z\n const xx = x * x2, xy = x * y2, xz = x * z2\n const yy = y * y2, yz = y * z2, zz = z * z2\n const wx = w * x2, wy = w * y2, wz = w * z2\n const sx = s[0], sy = s[1], sz = s[2]\n out[0] = (1 - (yy + zz)) * sx; out[1] = (xy + wz) * sx; out[2] = (xz - wy) * sx; out[3] = 0\n out[4] = (xy - wz) * sy; out[5] = (1 - (xx + zz)) * sy; out[6] = (yz + wx) * sy; out[7] = 0\n out[8] = (xz + wy) * sz; out[9] = (yz - wx) * sz; out[10] = (1 - (xx + yy)) * sz; out[11] = 0\n out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1\n return out\n}\n\n/** Orthographic projection with a -1..1 clip-space depth range. @template {Mat4Like} T @param {T} out @param {number} left @param {number} right @param {number} bottom @param {number} top @param {number} near @param {number} far @returns {T} */\nexport function ortho(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right), bt = 1 / (bottom - top), nf = 1 / (near - far)\n out.fill(0)\n out[0] = -2 * lr\n out[5] = -2 * bt\n out[10] = 2 * nf\n out[12] = (left + right) * lr\n out[13] = (top + bottom) * bt\n out[14] = (far + near) * nf\n out[15] = 1\n return out\n}\n\n// Model matrix placing an object at `eye` with its -Z axis pointing at `target` - the inverse of\n// a lookAt view matrix. Used to aim cameras, lights and nodes.\n/** @template {Mat4Like} T @param {T} out @param {Vec3Like} eye @param {Vec3Like} target @param {Vec3Like} up @returns {T} */\nexport function targetTo(out, eye, target, up) {\n const ex = eye[0], ey = eye[1], ez = eye[2]\n let z0 = ex - target[0], z1 = ey - target[1], z2 = ez - target[2]\n let len = z0 * z0 + z1 * z1 + z2 * z2\n if (len > 0) {\n len = 1 / Math.sqrt(len)\n z0 *= len; z1 *= len; z2 *= len\n }\n let x0 = up[1] * z2 - up[2] * z1, x1 = up[2] * z0 - up[0] * z2, x2 = up[0] * z1 - up[1] * z0\n len = x0 * x0 + x1 * x1 + x2 * x2\n if (len > 0) {\n len = 1 / Math.sqrt(len)\n x0 *= len; x1 *= len; x2 *= len\n }\n out[0] = x0; out[1] = x1; out[2] = x2; out[3] = 0\n out[4] = z1 * x2 - z2 * x1; out[5] = z2 * x0 - z0 * x2; out[6] = z0 * x1 - z1 * x0; out[7] = 0\n out[8] = z0; out[9] = z1; out[10] = z2; out[11] = 0\n out[12] = ex; out[13] = ey; out[14] = ez; out[15] = 1\n return out\n}\n","// 3D vectors as Float32Array(3). Signatures follow gl-matrix: results are written to `out`,\n// which is also returned. Functions only read and write the first three components, so a vec4\n// can be passed where a vec3 is expected (its w is left alone).\n\n/** @typedef {Float32Array | number[]} Vec3Like */\n\n/** @returns {Float32Array} */\nexport const create = () => new Float32Array(3)\n\n/** @param {number} x @param {number} y @param {number} z @returns {Float32Array} */\nexport function fromValues(x, y, z) {\n const out = new Float32Array(3)\n out[0] = x\n out[1] = y\n out[2] = z\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @returns {T} */\nexport function add(out, a, b) {\n out[0] = a[0] + b[0]\n out[1] = a[1] + b[1]\n out[2] = a[2] + b[2]\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @returns {T} */\nexport function subtract(out, a, b) {\n out[0] = a[0] - b[0]\n out[1] = a[1] - b[1]\n out[2] = a[2] - b[2]\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {number} s @returns {T} */\nexport function scale(out, a, s) {\n out[0] = a[0] * s\n out[1] = a[1] * s\n out[2] = a[2] * s\n return out\n}\n\n/** out = a + b * s @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @param {number} s @returns {T} */\nexport function scaleAndAdd(out, a, b, s) {\n out[0] = a[0] + b[0] * s\n out[1] = a[1] + b[1] * s\n out[2] = a[2] + b[2] * s\n return out\n}\n\n/** @param {Vec3Like} a @param {Vec3Like} b @returns {number} */\nexport const dot = (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @returns {T} */\nexport function cross(out, a, b) {\n const ax = a[0], ay = a[1], az = a[2]\n const bx = b[0], by = b[1], bz = b[2]\n out[0] = ay * bz - az * by\n out[1] = az * bx - ax * bz\n out[2] = ax * by - ay * bx\n return out\n}\n\n/** @param {Vec3Like} a @returns {number} */\nexport const length = (a) => Math.hypot(a[0], a[1], a[2])\n\n/** @param {Vec3Like} a @param {Vec3Like} b @returns {number} */\nexport const distance = (a, b) => Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2])\n\n// A zero vector normalises to zero rather than NaN.\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @returns {T} */\nexport function normalize(out, a) {\n const x = a[0], y = a[1], z = a[2]\n let len = x * x + y * y + z * z\n if (len > 0) len = 1 / Math.sqrt(len)\n out[0] = x * len\n out[1] = y * len\n out[2] = z * len\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Float32Array | number[]} m 3x3 column-major @returns {T} */\nexport function transformMat3(out, a, m) {\n const x = a[0], y = a[1], z = a[2]\n out[0] = x * m[0] + y * m[3] + z * m[6]\n out[1] = x * m[1] + y * m[4] + z * m[7]\n out[2] = x * m[2] + y * m[5] + z * m[8]\n return out\n}\n\n/** Transform a point by a 4x4, dividing by w. @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Float32Array | number[]} m @returns {T} */\nexport function transformMat4(out, a, m) {\n const x = a[0], y = a[1], z = a[2]\n const w = (m[3] * x + m[7] * y + m[11] * z + m[15]) || 1\n out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w\n out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w\n out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w\n return out\n}\n\n/** Rotate a vector by a quaternion. @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Float32Array | number[]} q @returns {T} */\nexport function transformQuat(out, a, q) {\n const qx = q[0], qy = q[1], qz = q[2], qw = q[3]\n const x = a[0], y = a[1], z = a[2]\n // v' = v + 2w(q x v) + 2(q x (q x v))\n let uvx = qy * z - qz * y, uvy = qz * x - qx * z, uvz = qx * y - qy * x\n let uuvx = qy * uvz - qz * uvy, uuvy = qz * uvx - qx * uvz, uuvz = qx * uvy - qy * uvx\n const w2 = qw * 2\n uvx *= w2; uvy *= w2; uvz *= w2\n uuvx *= 2; uuvy *= 2; uuvz *= 2\n out[0] = x + uvx + uuvx\n out[1] = y + uvy + uuvy\n out[2] = z + uvz + uuvz\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @param {Vec3Like} b @param {number} t @returns {T} */\nexport function lerp(out, a, b, t) {\n out[0] = a[0] + t * (b[0] - a[0])\n out[1] = a[1] + t * (b[1] - a[1])\n out[2] = a[2] + t * (b[2] - a[2])\n return out\n}\n\n/** @template {Vec3Like} T @param {T} out @param {Vec3Like} a @returns {T} */\nexport function negate(out, a) {\n out[0] = -a[0]\n out[1] = -a[1]\n out[2] = -a[2]\n return out\n}\n","// Validation helpers. Options and descriptions are checked once, when an object is created or a\n// property set - never per frame - and errors name the object, the problem and the fix.\n\n/** Error thrown for invalid phoria2 input. Its message always says what to do instead. */\nexport class PhoriaError extends Error {\n name = 'PhoriaError'\n}\n\n/**\n * Throw a PhoriaError: `${owner}: ${message}`.\n * @param {string} owner the object or function the input was for, e.g. 'Mesh' or 'box()'\n * @param {string} message\n * @returns {never}\n */\nexport function fail(owner, message) {\n throw new PhoriaError(`${owner}: ${message}`)\n}\n\n// Edit distance where swapping two neighbouring letters counts as one edit ('widht' -> 'width'),\n// for did-you-mean suggestions.\nfunction distance(a, b) {\n const d = Array.from({ length: a.length + 1 }, (_, i) => Array.from({ length: b.length + 1 }, (_, j) => (i ? (j ? 0 : i) : j)))\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1\n d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost)\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1)\n }\n }\n return d[a.length][b.length]\n}\n\n/**\n * The closest candidate to a mistyped name, or undefined if nothing is close.\n * @param {string} name\n * @param {Iterable<string>} candidates\n * @returns {string | undefined}\n */\nexport function suggest(name, candidates) {\n const lower = name.toLowerCase()\n // a list, since an iterator could only be read once\n const list = [...candidates]\n // an abbreviation that only one candidate starts with ('w' -> 'width')\n const prefixed = list.filter((c) => c.toLowerCase().startsWith(lower))\n if (prefixed.length === 1) return prefixed[0]\n let best, bestScore = Infinity\n for (const c of list) {\n const score = c.toLowerCase() === lower ? 0 : distance(lower, c.toLowerCase())\n if (score < bestScore) {\n best = c\n bestScore = score\n }\n }\n // allow roughly one edit per three characters\n return bestScore <= Math.max(1, Math.floor(name.length / 3)) ? best : undefined\n}\n\n/** \" - did you mean 'x'?\" or an empty string. @param {string} name @param {Iterable<string>} candidates */\nexport const didYouMean = (name, candidates) => {\n const s = suggest(name, candidates)\n return s ? ` - did you mean '${s}'?` : ''\n}\n\n/**\n * Check an options object only uses known keys. Known three.js-isms can map to a targeted hint.\n * @param {string} owner\n * @param {object} options\n * @param {Iterable<string>} known\n * @param {Record<string, string>} [hints] option name -> message for common mistakes\n * @param {string} [name] the option these are, when nested (e.g. 'framing'), so errors say which\n */\nexport function checkOptions(owner, options, known, hints = {}, name) {\n if (options == null) return\n const keys = new Set(known)\n if (typeof options !== 'object' || Array.isArray(options)) {\n const expected = name ? `'${name}' must be an options object - { ${[...keys].join(', ')} }` : 'expected an options object'\n fail(owner, `${expected}, got ${describe(options)}`)\n }\n for (const key of Object.keys(options)) {\n if (keys.has(key)) continue\n if (hints[key]) fail(owner, hints[key])\n fail(owner, `unknown option '${name ? `${name}.${key}` : key}'${didYouMean(key, keys)}`)\n }\n}\n\n/** A short description of a value for error messages. @param {unknown} v @returns {string} */\nexport function describe(v) {\n if (v === null) return 'null'\n if (Array.isArray(v)) return `an array of ${v.length}`\n if (typeof v === 'string') return `'${v}'`\n if (typeof v === 'object') return v.constructor?.name && v.constructor !== Object ? `a ${v.constructor.name}` : 'an object'\n return String(v)\n}\n\n/** @param {string} owner @param {string} name @param {unknown} v @returns {number} */\nexport function checkNumber(owner, name, v) {\n if (typeof v !== 'number' || Number.isNaN(v)) fail(owner, `'${name}' must be a number, got ${describe(v)}`)\n return v\n}\n\n/**\n * A number within limits: from min (or above it, with above: true) up to max.\n * @param {string} owner @param {string} name @param {unknown} v\n * @param {number} [min] @param {number} [max] @param {{ above?: boolean }} [options]\n * @returns {number}\n */\nexport function checkRange(owner, name, v, min = -Infinity, max = Infinity, { above = false } = {}) {\n const n = checkNumber(owner, name, v)\n if ((above ? !(n > min) : n < min) || n > max) {\n const limits = max === Infinity ? (above ? `above ${min}` : `${min} or more`) : above ? `above ${min} and up to ${max}` : `from ${min} to ${max}`\n fail(owner, `'${name}' must be ${limits}, got ${n}`)\n }\n return n\n}\n\n/**\n * @template {string} T\n * @param {string} owner @param {string} name @param {unknown} v @param {readonly T[]} allowed\n * @returns {T}\n */\nexport function checkOneOf(owner, name, v, allowed) {\n if (!allowed.includes(/** @type {T} */ (v))) {\n const hint = typeof v === 'string' ? didYouMean(v, allowed) : ''\n fail(owner, `'${name}' ${describe(v)} is not valid - expected ${allowed.map((a) => `'${a}'`).join(' | ')}${hint}`)\n }\n return /** @type {T} */ (v)\n}\n\nconst warned = new WeakMap()\n/**\n * console.warn once per object and message - for problems that would otherwise repeat every frame.\n * @param {object} target @param {string} message\n */\nexport function warnOnce(target, message) {\n let seen = warned.get(target)\n if (!seen) warned.set(target, seen = new Set())\n if (seen.has(message)) return\n seen.add(message)\n console.warn(`phoria2: ${message}`)\n}\n\n/**\n * A generator's options: an options object, or a number standing for its main size - checked against\n * the names it takes.\n * @param {string} owner @param {unknown} options @param {string[]} keys\n * @param {((n: number) => object) | null} fromNumber @param {Record<string, string>} [hints]\n * @returns {Record<string, any>}\n */\nexport function resolveOptions(owner, options, keys, fromNumber, hints) {\n const o = /** @type {object} */ (typeof options === 'number' && fromNumber ? fromNumber(options) : options)\n checkOptions(owner, o, keys, hints)\n return o ?? {}\n}\n\n/**\n * A length: a finite number above 0 (or 0 itself when `zero`), or the default when missing.\n * @param {string} owner @param {string} name @param {unknown} value @param {number} fallback\n * @param {boolean} [zero]\n * @returns {number}\n */\nexport function checkLength(owner, name, value, fallback, zero = false) {\n if (value === undefined) return fallback\n const n = checkNumber(owner, name, value)\n if (!Number.isFinite(n) || n < 0 || (n === 0 && !zero)) fail(owner, `'${name}' must be ${zero ? '0 or more' : 'more than 0'}, got ${n}`)\n return n\n}\n\n/**\n * A whole number - segments, sides, points - in [min, max], or the default when missing.\n * @param {string} owner @param {string} name @param {unknown} value @param {number} fallback\n * @param {number} [min] @param {number} [max]\n * @returns {number}\n */\nexport function checkCount(owner, name, value, fallback, min = 1, max = Infinity) {\n if (value === undefined) return fallback\n if (!Number.isInteger(value) || /** @type {number} */ (value) < min || /** @type {number} */ (value) > max) {\n fail(owner, `'${name}' must be a whole number ${max === Infinity ? `${min} or more` : `from ${min} to ${max}`}, got ${describe(value)}`)\n }\n return /** @type {number} */ (value)\n}\n","import * as vec3 from '../math/vec3.js'\nimport { checkNumber, describe, fail } from '../validate.js'\n\n/** @import { Vec3Input } from '../types.js' */\n\n/**\n * A 3D vector: a Float32Array(3) with x/y/z accessors and chainable methods, so it works both with\n * the vec3/mat4 functions and three.js-style code (`position.set(1, 2, 3)`, `position.x += 1`).\n */\nexport class Vec3 extends Float32Array {\n // slice(), map() etc. return plain Float32Arrays rather than calling this constructor\n static get [Symbol.species]() { return Float32Array }\n\n /** @param {number} [x] @param {number} [y] @param {number} [z] */\n constructor(x = 0, y = 0, z = 0) {\n super(3)\n this[0] = x\n this[1] = y\n this[2] = z\n }\n\n /** @internal\n * Convert input to a new Vec3: [x, y, z], { x, y, z }, a Vec3, or one number for all three.\n * @param {Vec3Input | number} v\n * @param {string} [owner] for error messages\n * @returns {Vec3}\n */\n static fromInput(v, owner = 'Vec3') {\n return new Vec3().copy(v, owner)\n }\n\n get x() { return this[0] }\n set x(v) { this[0] = v }\n get y() { return this[1] }\n set y(v) { this[1] = v }\n get z() { return this[2] }\n set z(v) { this[2] = v }\n\n /**\n * set(x, y, z) sets the components, three.js style. set(array, offset) keeps the typed array\n * behaviour.\n * @overload\n * @param {number} x @param {number} y @param {number} z\n * @returns {this}\n */\n /**\n * @overload\n * @param {ArrayLike<number>} array @param {number} [offset]\n * @returns {void}\n */\n /** @param {number | ArrayLike<number>} x @param {number} [y] @param {number} [z] */\n set(x, y, z) {\n if (typeof x !== 'number') {\n super.set(x, y ?? 0)\n return\n }\n this[0] = x\n this[1] = y ?? this[1]\n this[2] = z ?? this[2]\n return this\n }\n\n /** Set all three to one number - a uniform scale: `node.scale.setScalar(2)`. @param {number} s @returns {this} */\n setScalar(s) {\n this[0] = this[1] = this[2] = checkNumber('Vec3', 'setScalar', s)\n return this\n }\n\n /** Copy from any Vec3Input, or one number for all three. @param {Vec3Input | number} v @param {string} [owner] @returns {this} */\n copy(v, owner = 'Vec3') {\n if (typeof v === 'number') {\n this[0] = this[1] = this[2] = v\n } else if (v && (Array.isArray(v) || ArrayBuffer.isView(v)) && v.length >= 3) {\n this[0] = v[0]\n this[1] = v[1]\n this[2] = v[2]\n } else if (v && typeof v === 'object' && 'x' in v && 'y' in v && 'z' in v) {\n this[0] = v.x\n this[1] = v.y\n this[2] = v.z\n } else {\n fail(owner, `expected [x, y, z] or { x, y, z }, got ${describe(v)}`)\n }\n if (Number.isNaN(this[0] + this[1] + this[2])) fail(owner, `vector components must be numbers, got ${describe(v)}`)\n return this\n }\n\n /** @returns {Vec3} */\n clone() {\n return new Vec3(this[0], this[1], this[2])\n }\n\n /** @param {Vec3Input} v @returns {this} */\n add(v) {\n const o = toArray(v)\n return vec3.add(this, this, o)\n }\n\n /** @param {Vec3Input} v @returns {this} */\n sub(v) {\n return vec3.subtract(this, this, toArray(v))\n }\n\n /** @param {number} s @returns {this} */\n multiplyScalar(s) {\n return vec3.scale(this, this, s)\n }\n\n /** @returns {this} */\n normalize() {\n return vec3.normalize(this, this)\n }\n\n /** @returns {this} */\n negate() {\n return vec3.negate(this, this)\n }\n\n /** @param {Vec3Input} v @param {number} t @returns {this} */\n lerp(v, t) {\n return vec3.lerp(this, this, toArray(v), t)\n }\n\n /** @param {Vec3Input} v @returns {this} */\n cross(v) {\n return vec3.cross(this, this, toArray(v))\n }\n\n /** @param {Vec3Input} v @returns {number} */\n dot(v) {\n return vec3.dot(this, toArray(v))\n }\n\n // len(), not length(): a typed array already has a length property (3)\n /** @returns {number} */\n len() {\n return vec3.length(this)\n }\n\n /** @param {Vec3Input} v @returns {number} */\n distanceTo(v) {\n return vec3.distance(this, toArray(v))\n }\n\n /** Transform as a point (w = 1). @param {Float32Array | number[]} m 4x4 @returns {this} */\n applyMatrix4(m) {\n return vec3.transformMat4(this, this, m)\n }\n\n /** @param {Float32Array | number[]} q @returns {this} */\n applyQuaternion(q) {\n return vec3.transformQuat(this, this, q)\n }\n\n /** @param {Vec3Input} v @param {number} [epsilon] @returns {boolean} */\n equals(v, epsilon = 0) {\n const o = toArray(v)\n return Math.abs(this[0] - o[0]) <= epsilon && Math.abs(this[1] - o[1]) <= epsilon && Math.abs(this[2] - o[2]) <= epsilon\n }\n\n /** @returns {[number, number, number]} */\n toArray() {\n return [this[0], this[1], this[2]]\n }\n\n toJSON() {\n return this.toArray()\n }\n}\n\n/** @param {Vec3Input} v @returns {Float32Array | number[]} */\nfunction toArray(v) {\n return Array.isArray(v) || ArrayBuffer.isView(v) ? /** @type {Float32Array | number[]} */ (v) : Vec3.fromInput(v)\n}\n","import * as mat4 from '../math/mat4.js'\nimport { Vec3 } from './Vec3.js'\n\n/** A 4x4 matrix: a column-major Float32Array(16), identity by default, with a few chainable methods. */\nexport class Mat4 extends Float32Array {\n static get [Symbol.species]() { return Float32Array }\n\n constructor() {\n super(16)\n this[0] = this[5] = this[10] = this[15] = 1\n }\n\n /** @returns {this} */\n identity() {\n return mat4.identity(this)\n }\n\n /** @param {ArrayLike<number>} m @returns {this} */\n copy(m) {\n for (let i = 0; i < 16; i++) this[i] = m[i]\n return this\n }\n\n /** @returns {Mat4} */\n clone() {\n return new Mat4().copy(this)\n }\n\n /** this = this * m @param {ArrayLike<number>} m @returns {this} */\n multiply(m) {\n return mat4.multiply(this, this, /** @type {number[]} */ (m))\n }\n\n /** this = a * b @param {ArrayLike<number>} a @param {ArrayLike<number>} b @returns {this} */\n multiplyMatrices(a, b) {\n return mat4.multiply(this, /** @type {number[]} */ (a), /** @type {number[]} */ (b))\n }\n\n /** Invert in place; becomes all zeros if the matrix is singular. @returns {this} */\n invert() {\n if (!mat4.invert(this, this)) this.fill(0)\n return this\n }\n\n /** Compose from a translation, rotation and scale. @param {ArrayLike<number>} position @param {ArrayLike<number>} quaternion @param {ArrayLike<number>} scale @returns {this} */\n compose(position, quaternion, scale) {\n return mat4.fromRotationTranslationScale(this, /** @type {number[]} */ (quaternion), /** @type {number[]} */ (position), /** @type {number[]} */ (scale))\n }\n\n /** The translation part. @param {Vec3} [out] @returns {Vec3} */\n getPosition(out = new Vec3()) {\n return out.set(this[12], this[13], this[14])\n }\n\n /** The length of each basis vector. @param {Vec3} [out] @returns {Vec3} */\n getScale(out = new Vec3()) {\n return out.set(\n Math.hypot(this[0], this[1], this[2]),\n Math.hypot(this[4], this[5], this[6]),\n Math.hypot(this[8], this[9], this[10]))\n }\n\n /** @returns {number[]} */\n toArray() {\n return Array.from(this)\n }\n}\n","import { Vec3 } from './Vec3.js'\n\n/** An axis aligned bounding box. Empty (min > max) until a point is added. */\nexport class Box3 {\n min = new Vec3(Infinity, Infinity, Infinity)\n max = new Vec3(-Infinity, -Infinity, -Infinity)\n\n /** @param {ArrayLike<number>} [min] @param {ArrayLike<number>} [max] */\n constructor(min, max) {\n if (min) this.min.set(min[0], min[1], min[2])\n if (max) this.max.set(max[0], max[1], max[2])\n }\n\n /** @returns {this} */\n makeEmpty() {\n this.min.set(Infinity, Infinity, Infinity)\n this.max.set(-Infinity, -Infinity, -Infinity)\n return this\n }\n\n /** @returns {boolean} */\n isEmpty() {\n return this.max[0] < this.min[0] || this.max[1] < this.min[1] || this.max[2] < this.min[2]\n }\n\n /** @param {number} x @param {number} y @param {number} z @returns {this} */\n expandByXYZ(x, y, z) {\n const { min, max } = this\n if (x < min[0]) min[0] = x\n if (y < min[1]) min[1] = y\n if (z < min[2]) min[2] = z\n if (x > max[0]) max[0] = x\n if (y > max[1]) max[1] = y\n if (z > max[2]) max[2] = z\n return this\n }\n\n /** @param {ArrayLike<number>} p @returns {this} */\n expandByPoint(p) {\n return this.expandByXYZ(p[0], p[1], p[2])\n }\n\n /** Grow to contain flat xyz positions. @param {ArrayLike<number>} positions @returns {this} */\n expandByPositions(positions) {\n for (let i = 0; i < positions.length; i += 3) this.expandByXYZ(positions[i], positions[i + 1], positions[i + 2])\n return this\n }\n\n /** @param {Box3} box @returns {this} */\n union(box) {\n if (box.isEmpty()) return this\n this.expandByPoint(box.min)\n return this.expandByPoint(box.max)\n }\n\n /** Transform by a 4x4, keeping it axis aligned (bounds of the 8 transformed corners). @param {ArrayLike<number>} m @returns {this} */\n applyMatrix4(m) {\n if (this.isEmpty()) return this\n const [x0, y0, z0] = this.min, [x1, y1, z1] = this.max\n this.makeEmpty()\n for (const x of [x0, x1]) {\n for (const y of [y0, y1]) {\n for (const z of [z0, z1]) {\n this.expandByXYZ(\n m[0] * x + m[4] * y + m[8] * z + m[12],\n m[1] * x + m[5] * y + m[9] * z + m[13],\n m[2] * x + m[6] * y + m[10] * z + m[14])\n }\n }\n }\n return this\n }\n\n /** @param {Vec3} [out] @returns {Vec3} */\n getCenter(out = new Vec3()) {\n if (this.isEmpty()) return out.set(0, 0, 0)\n return out.set((this.min[0] + this.max[0]) / 2, (this.min[1] + this.max[1]) / 2, (this.min[2] + this.max[2]) / 2)\n }\n\n /** @param {Vec3} [out] @returns {Vec3} */\n getSize(out = new Vec3()) {\n if (this.isEmpty()) return out.set(0, 0, 0)\n return out.set(this.max[0] - this.min[0], this.max[1] - this.min[1], this.max[2] - this.min[2])\n }\n\n /** Radius of the sphere around getCenter() that contains the box. @returns {number} */\n getRadius() {\n return this.isEmpty() ? 0 : this.getSize().len() / 2\n }\n\n /** @param {ArrayLike<number>} p @returns {boolean} */\n containsPoint(p) {\n return p[0] >= this.min[0] && p[0] <= this.max[0] &&\n p[1] >= this.min[1] && p[1] <= this.max[1] &&\n p[2] >= this.min[2] && p[2] <= this.max[2]\n }\n\n /** @returns {Box3} */\n clone() {\n return new Box3(this.min, this.max)\n }\n\n /** @param {Box3} box @returns {this} */\n copy(box) {\n this.min.set(box.min[0], box.min[1], box.min[2])\n this.max.set(box.max[0], box.max[1], box.max[2])\n return this\n }\n}\n","// Where a directional light's shadow map looks: fitted every frame to what casts shadows, so there\n// is no shadow camera to configure. In the light's view a shadow only travels along the depth,\n// so the casters' extent across the view is all the map has to cover; the depth runs on to the\n// furthest receiver.\nimport * as mat4 from './math/mat4.js'\nimport { Mat4 } from './value/Mat4.js'\n\n/** @import { Box3 } from './value/Box3.js' */\n\n/** Shadow map size in texels. */\nexport const SHADOW_MAP_SIZE = 2048\n\n/**\n * @typedef {object} ShadowFit\n * @property {Mat4} viewProjection world to the light's clip space\n * @property {number} texelSize world units per shadow map texel\n */\n\n/**\n * Fit a directional light's shadow view to the world bounds of the casters (and the depth of the\n * receivers). Null when nothing casts.\n * @param {ArrayLike<number>} direction the way the light travels\n * @param {Box3[]} casters world bounds\n * @param {Box3[]} receivers world bounds\n * @param {number} [size] map size in texels\n * @param {Box3 | null} [area] the light's shadowBounds: the map covers this across, whatever casts\n * @returns {ShadowFit | null}\n */\nexport function fitShadow(direction, casters, receivers, size = SHADOW_MAP_SIZE, area = null) {\n const boxes = casters.filter((b) => !b.isEmpty())\n if (!boxes.length) return null\n const d = normalized(direction)\n // look along the light from the origin; only the orientation matters, the box comes next\n const up = Math.abs(d[1]) > 0.99 ? [0, 0, 1] : [0, 1, 0]\n const view = mat4.lookAt(mat4.create(), [0, 0, 0], d, up)\n\n let x0 = Infinity, x1 = -Infinity, y0 = Infinity, y1 = -Infinity, z0 = Infinity, z1 = -Infinity\n const corners = (/** @type {Box3} */ b, /** @type {boolean} */ across) => {\n for (let i = 0; i < 8; i++) {\n const px = i & 1 ? b.max[0] : b.min[0], py = i & 2 ? b.max[1] : b.min[1], pz = i & 4 ? b.max[2] : b.min[2]\n const x = view[0] * px + view[4] * py + view[8] * pz\n const y = view[1] * px + view[5] * py + view[9] * pz\n const z = view[2] * px + view[6] * py + view[10] * pz\n if (across) {\n if (x < x0) x0 = x\n if (x > x1) x1 = x\n if (y < y0) y0 = y\n if (y > y1) y1 = y\n }\n if (z < z0) z0 = z\n if (z > z1) z1 = z\n }\n }\n // across the light's view: the area it was given, or else the casters; in depth, everything that\n // casts - so a caster outside the area, between it and the light, still shadows it\n if (area) corners(area, true)\n for (const b of boxes) corners(b, !area)\n // receivers only stretch the depth (view z is negative in front, so the far end is the minimum)\n for (const b of receivers) if (!b.isEmpty()) corners(b, false)\n\n // a small margin, so the soft edge of the outermost caster's shadow isn't clipped\n const margin = Math.max(x1 - x0, y1 - y0, 1e-3) * 0.02\n x0 -= margin; x1 += margin; y0 -= margin; y1 += margin\n const depthMargin = Math.max(z1 - z0, 1e-3) * 0.01\n z0 -= depthMargin; z1 += depthMargin\n\n // steady while things move: the map grows and shrinks in small steps rather than with every change\n // in the casters' extent, and its edges sit on the texel grid, so a shadow that isn't moving falls\n // on the same texels every frame, instead of shimmering as the fit slides about under it\n const w = steps(x1 - x0), h = steps(y1 - y0)\n const tx = w / size, ty = h / size\n x0 = Math.floor((x0 + x1 - w) / 2 / tx) * tx\n y0 = Math.floor((y0 + y1 - h) / 2 / ty) * ty\n // the depth range too, which sets what each stored depth means\n const dz = steps(z1 - z0) / 64\n z0 = Math.floor(z0 / dz) * dz\n z1 = Math.ceil(z1 / dz) * dz\n\n const projection = mat4.ortho(mat4.create(), x0, x0 + w, y0, y0 + h, -z1, -z0)\n const viewProjection = new Mat4()\n mat4.multiply(viewProjection, projection, view)\n return { viewProjection, texelSize: Math.max(w, h) / size }\n}\n\n/** A length rounded up to the next of a ladder of sizes, sixteen to each doubling. @param {number} v */\nfunction steps(v) {\n return 2 ** (Math.ceil(Math.log2(Math.max(v, 1e-3)) * 16) / 16)\n}\n\n/** Spot shadows' map: four tiles of half its size, one a light. */\nexport const SPOT_ATLAS_SIZE = 2048\nexport const SPOT_TILES = 4\n\n/**\n * A spot light's view for its shadow: from the light along its cone, wide enough for the cone,\n * from just short of the nearest caster to the furthest receiver (or the light's range).\n * @param {ArrayLike<number>} position @param {ArrayLike<number>} direction\n * @param {number} angle the cone's half-angle @param {number} range 0 for unlimited\n * @param {Box3[]} casters @param {Box3[]} receivers\n * @returns {{ viewProjection: Mat4, texelAngle: number } | null} texelAngle: a shadow map texel's size at a distance of 1\n */\nexport function fitSpotShadow(position, direction, angle, range, casters, receivers) {\n const boxes = casters.filter((b) => !b.isEmpty())\n if (!boxes.length) return null\n const d = normalized(direction)\n const up = Math.abs(d[1]) > 0.99 ? [0, 0, 1] : [0, 1, 0]\n const eye = Float32Array.from(position), at = Float32Array.from([position[0] + d[0], position[1] + d[1], position[2] + d[2]])\n const view = mat4.lookAt(mat4.create(), eye, at, Float32Array.from(up))\n let near = Infinity, far = 0\n const depths = (/** @type {Box3} */ b, /** @type {boolean} */ caster) => {\n for (let i = 0; i < 8; i++) {\n const px = i & 1 ? b.max[0] : b.min[0], py = i & 2 ? b.max[1] : b.min[1], pz = i & 4 ? b.max[2] : b.min[2]\n const z = -(view[2] * px + view[6] * py + view[10] * pz + view[14])\n if (caster && z < near) near = z\n if (z > far) far = z\n }\n }\n for (const b of boxes) depths(b, true)\n for (const b of receivers) if (!b.isEmpty()) depths(b, false)\n near = Math.max(0.05, near * 0.9)\n if (range > 0) far = Math.min(far, range)\n far = Math.max(far * 1.02, near * 2)\n // a little wider than the cone, so its soft edge isn't cut off\n const fov = Math.min(2 * angle * 1.1 + 0.05, Math.PI * 0.95)\n const projection = mat4.perspective(mat4.create(), fov, 1, near, far)\n const viewProjection = new Mat4()\n mat4.multiply(viewProjection, projection, view)\n return { viewProjection, texelAngle: 2 * Math.tan(fov / 2) / (SPOT_ATLAS_SIZE / 2) }\n}\n\n/** A point light's shadow: a cube of six square faces, each this many texels across. */\nexport const POINT_SHADOW_SIZE = 1024\n\n// the cube's faces in GL's order (+X, -X, +Y, -Y, +Z, -Z): which way each looks, and its up -\n// upside down, as cube maps are stored\nconst CUBE_FACES = [\n [[1, 0, 0], [0, -1, 0]], [[-1, 0, 0], [0, -1, 0]],\n [[0, 1, 0], [0, 0, 1]], [[0, -1, 0], [0, 0, -1]],\n [[0, 0, 1], [0, -1, 0]], [[0, 0, -1], [0, -1, 0]],\n]\n\n/**\n * A point light's six views for its shadow, a right angle each, from close to the light out to the\n * furthest receiver (or the light's range). Null when nothing casts.\n * @param {ArrayLike<number>} position @param {number} range 0 for unlimited\n * @param {Box3[]} casters @param {Box3[]} receivers\n * @returns {{ viewProjections: Mat4[], near: number, far: number, texelAngle: number } | null} texelAngle: a texel's size at a distance of 1\n */\nexport function fitPointShadow(position, range, casters, receivers) {\n const boxes = casters.filter((b) => !b.isEmpty())\n if (!boxes.length) return null\n // out to the furthest corner of anything casting or receiving\n let far = 0\n for (const b of [...boxes, ...receivers]) {\n if (b.isEmpty()) continue\n for (let i = 0; i < 8; i++) {\n const dx = (i & 1 ? b.max[0] : b.min[0]) - position[0]\n const dy = (i & 2 ? b.max[1] : b.min[1]) - position[1]\n const dz = (i & 4 ? b.max[2] : b.min[2]) - position[2]\n far = Math.max(far, Math.hypot(dx, dy, dz))\n }\n }\n if (range > 0) far = Math.min(far, range)\n far = Math.max(far * 1.02, 1e-3)\n // a caster can wrap the light - a lantern, a pumpkin - so the near plane can't wait for the\n // nearest caster; a fraction of the far one keeps the depth precise\n const near = far * 2e-3\n const projection = mat4.perspective(mat4.create(), Math.PI / 2, 1, near, far)\n const eye = Float32Array.from(position)\n const viewProjections = CUBE_FACES.map(([d, up]) => {\n const at = Float32Array.from([eye[0] + d[0], eye[1] + d[1], eye[2] + d[2]])\n const view = mat4.lookAt(mat4.create(), eye, at, Float32Array.from(up))\n return /** @type {Mat4} */ (mat4.multiply(new Mat4(), projection, view))\n })\n return { viewProjections, near, far, texelAngle: 2 / POINT_SHADOW_SIZE }\n}\n\n/** @param {ArrayLike<number>} v @returns {number[]} */\nfunction normalized(v) {\n const len = Math.hypot(v[0], v[1], v[2]) || 1\n return [v[0] / len, v[1] / len, v[2] / len]\n}\n","// The 148 CSS named colours (CSS Color Module Level 4), as name:rrggbb pairs. Kept as one string\n// because it compresses far better than an object literal.\nconst TABLE =\n 'aliceblue:f0f8ff,antiquewhite:faebd7,aqua:00ffff,aquamarine:7fffd4,azure:f0ffff,beige:f5f5dc,' +\n 'bisque:ffe4c4,black:000000,blanchedalmond:ffebcd,blue:0000ff,blueviolet:8a2be2,brown:a52a2a,' +\n 'burlywood:deb887,cadetblue:5f9ea0,chartreuse:7fff00,chocolate:d2691e,coral:ff7f50,' +\n 'cornflowerblue:6495ed,cornsilk:fff8dc,crimson:dc143c,cyan:00ffff,darkblue:00008b,darkcyan:008b8b,' +\n 'darkgoldenrod:b8860b,darkgray:a9a9a9,darkgreen:006400,darkgrey:a9a9a9,darkkhaki:bdb76b,' +\n 'darkmagenta:8b008b,darkolivegreen:556b2f,darkorange:ff8c00,darkorchid:9932cc,darkred:8b0000,' +\n 'darksalmon:e9967a,darkseagreen:8fbc8f,darkslateblue:483d8b,darkslategray:2f4f4f,' +\n 'darkslategrey:2f4f4f,darkturquoise:00ced1,darkviolet:9400d3,deeppink:ff1493,deepskyblue:00bfff,' +\n 'dimgray:696969,dimgrey:696969,dodgerblue:1e90ff,firebrick:b22222,floralwhite:fffaf0,' +\n 'forestgreen:228b22,fuchsia:ff00ff,gainsboro:dcdcdc,ghostwhite:f8f8ff,gold:ffd700,goldenrod:daa520,' +\n 'gray:808080,green:008000,greenyellow:adff2f,grey:808080,honeydew:f0fff0,hotpink:ff69b4,' +\n 'indianred:cd5c5c,indigo:4b0082,ivory:fffff0,khaki:f0e68c,lavender:e6e6fa,lavenderblush:fff0f5,' +\n 'lawngreen:7cfc00,lemonchiffon:fffacd,lightblue:add8e6,lightcoral:f08080,lightcyan:e0ffff,' +\n 'lightgoldenrodyellow:fafad2,lightgray:d3d3d3,lightgreen:90ee90,lightgrey:d3d3d3,lightpink:ffb6c1,' +\n 'lightsalmon:ffa07a,lightseagreen:20b2aa,lightskyblue:87cefa,lightslategray:778899,' +\n 'lightslategrey:778899,lightsteelblue:b0c4de,lightyellow:ffffe0,lime:00ff00,limegreen:32cd32,' +\n 'linen:faf0e6,magenta:ff00ff,maroon:800000,mediumaquamarine:66cdaa,mediumblue:0000cd,' +\n 'mediumorchid:ba55d3,mediumpurple:9370db,mediumseagreen:3cb371,mediumslateblue:7b68ee,' +\n 'mediumspringgreen:00fa9a,mediumturquoise:48d1cc,mediumvioletred:c71585,midnightblue:191970,' +\n 'mintcream:f5fffa,mistyrose:ffe4e1,moccasin:ffe4b5,navajowhite:ffdead,navy:000080,oldlace:fdf5e6,' +\n 'olive:808000,olivedrab:6b8e23,orange:ffa500,orangered:ff4500,orchid:da70d6,palegoldenrod:eee8aa,' +\n 'palegreen:98fb98,paleturquoise:afeeee,palevioletred:db7093,papayawhip:ffefd5,peachpuff:ffdab9,' +\n 'peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple:800080,rebeccapurple:663399,' +\n 'red:ff0000,rosybrown:bc8f8f,royalblue:4169e1,saddlebrown:8b4513,salmon:fa8072,sandybrown:f4a460,' +\n 'seagreen:2e8b57,seashell:fff5ee,sienna:a0522d,silver:c0c0c0,skyblue:87ceeb,slateblue:6a5acd,' +\n 'slategray:708090,slategrey:708090,snow:fffafa,springgreen:00ff7f,steelblue:4682b4,tan:d2b48c,' +\n 'teal:008080,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,' +\n 'white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32'\n\n/** CSS colour name -> 0xrrggbb. @type {Map<string, number>} */\nexport const CSS_COLORS = new Map(TABLE.split(',').map((pair) => {\n const [name, hex] = pair.split(':')\n return [name, parseInt(hex, 16)]\n}))\n","import { describe, didYouMean, fail } from '../validate.js'\nimport { CSS_COLORS } from './cssColors.js'\n\n/** @import { ColorInput } from '../types.js' */\n\nconst toLinear = (c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4)\nconst toSRGB = (c) => (c <= 0.0031308 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055)\nconst clamp01 = (c) => Math.min(1, Math.max(0, c))\n\nconst NUMBER = String.raw`[-+]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?`\nconst FUNC = new RegExp(String.raw`^(rgba?|hsla?)\\(\\s*(${NUMBER})(%|deg)?[\\s,]+(${NUMBER})(%)?[\\s,]+(${NUMBER})(%)?(?:\\s*[,/]\\s*(${NUMBER})%?)?\\s*\\)$`, 'i')\n\nconst HELP = \"use '#rrggbb', a CSS name, 'rgb(...)', 'hsl(...)', 0xrrggbb or [r, g, b] with components 0-1\"\n\n/**\n * An RGB colour. Input is sRGB, as everywhere in phoria2; the components are stored **linear**,\n * ready for lighting maths. `toJSON()` gives sRGB '#rrggbb' back.\n */\n// colour strings already worked out, as linear rgb - emptied when full, as a palette never fills it\n/** @type {Map<string, number[]>} */\nconst PARSED = new Map()\nconst PARSED_MAX = 1024\n\nexport class Color extends Float32Array {\n static get [Symbol.species]() { return Float32Array }\n\n /** @param {ColorInput} [input] defaults to white */\n constructor(input = 0xffffff) {\n super(3)\n this.set(input)\n }\n\n /** @internal @param {ColorInput} input @param {string} [owner] for error messages @returns {Color} */\n static fromInput(input, owner = 'Color') {\n return new Color().set(input, owner)\n }\n\n /** Linear red. */\n get r() { return this[0] }\n set r(v) { this[0] = v }\n get g() { return this[1] }\n set g(v) { this[1] = v }\n get b() { return this[2] }\n set b(v) { this[2] = v }\n\n /**\n * Set from any colour input (sRGB).\n * @overload\n * @param {ColorInput} input @param {string} [owner]\n * @returns {this}\n */\n /**\n * @overload\n * @param {ArrayLike<number>} array @param {number} [offset]\n * @returns {void}\n */\n /** @param {any} input @param {any} [owner] */\n set(input, owner = 'Color') {\n if (typeof owner === 'number') {\n // typed array set(array, offset)\n super.set(input, owner)\n return\n }\n if (input instanceof Color) {\n this[0] = input[0]\n this[1] = input[1]\n this[2] = input[2]\n } else if (typeof input === 'number') {\n this.#setHex(input, owner)\n } else if (typeof input === 'string') {\n this.#setString(input.trim(), owner)\n } else if (Array.isArray(input) || ArrayBuffer.isView(input)) {\n const arr = /** @type {ArrayLike<number>} */ (input)\n if (arr.length < 3) fail(owner, `color ${describe(input)} needs 3 components [r, g, b]`)\n const r = arr[0], g = arr[1], b = arr[2]\n if ([r, g, b].some((c) => typeof c !== 'number' || Number.isNaN(c))) fail(owner, `color components must be numbers - ${HELP}`)\n if (r > 1 || g > 1 || b > 1) {\n fail(owner, `color [${r}, ${g}, ${b}] has components above 1 - components are 0-1, ` +\n `e.g. [${+(r / 255).toFixed(3)}, ${+(g / 255).toFixed(3)}, ${+(b / 255).toFixed(3)}]`)\n }\n this.setSRGB(r, g, b)\n } else {\n fail(owner, `${describe(input)} is not a colour - ${HELP}`)\n }\n return this\n }\n\n /** Set from sRGB components 0-1. @param {number} r @param {number} g @param {number} b @returns {this} */\n setSRGB(r, g, b) {\n this[0] = toLinear(r)\n this[1] = toLinear(g)\n this[2] = toLinear(b)\n return this\n }\n\n /** Set linear components directly. @param {number} r @param {number} g @param {number} b @returns {this} */\n setLinear(r, g, b) {\n this[0] = r\n this[1] = g\n this[2] = b\n return this\n }\n\n /** @returns {Color} */\n clone() {\n return new Color(this)\n }\n\n /** @param {number} s @returns {this} */\n multiplyScalar(s) {\n this[0] *= s\n this[1] *= s\n this[2] *= s\n return this\n }\n\n /**\n * Move towards another colour by t (0-1), mixing the linear components - as light mixes.\n * @param {ColorInput} c @param {number} t @returns {this}\n */\n lerp(c, t) {\n const o = c instanceof Color ? c : Color.fromInput(c)\n this[0] += (o[0] - this[0]) * t\n this[1] += (o[1] - this[1]) * t\n this[2] += (o[2] - this[2]) * t\n return this\n }\n\n /** sRGB components 0-1. @returns {[number, number, number]} */\n toSRGB() {\n return [clamp01(toSRGB(this[0])), clamp01(toSRGB(this[1])), clamp01(toSRGB(this[2]))]\n }\n\n /** sRGB as 0xrrggbb. @returns {number} */\n getHex() {\n const [r, g, b] = this.toSRGB()\n return (Math.round(r * 255) << 16) | (Math.round(g * 255) << 8) | Math.round(b * 255)\n }\n\n /** sRGB as '#rrggbb'. @returns {string} */\n getStyle() {\n return '#' + this.getHex().toString(16).padStart(6, '0')\n }\n\n /** @param {Color} c @param {number} [epsilon] @returns {boolean} */\n equals(c, epsilon = 1e-6) {\n return Math.abs(this[0] - c[0]) <= epsilon && Math.abs(this[1] - c[1]) <= epsilon && Math.abs(this[2] - c[2]) <= epsilon\n }\n\n toJSON() {\n return this.getStyle()\n }\n\n /** @param {number} hex @param {string} owner */\n #setHex(hex, owner) {\n if (!Number.isInteger(hex) || hex < 0 || hex > 0xffffff) fail(owner, `color ${hex} is not 0x000000-0xffffff - ${HELP}`)\n this.setSRGB(((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255)\n }\n\n /** @param {string} s @param {string} owner */\n #setString(s, owner) {\n // the same few strings come again and again - an instance's colour set every frame - so each is\n // worked out once\n const known = PARSED.get(s)\n if (known) {\n this[0] = known[0]\n this[1] = known[1]\n this[2] = known[2]\n return\n }\n this.#parse(s, owner)\n if (PARSED.size >= PARSED_MAX) PARSED.clear()\n PARSED.set(s, [this[0], this[1], this[2]])\n }\n\n /** @param {string} s @param {string} owner */\n #parse(s, owner) {\n const lower = s.toLowerCase()\n if (lower.startsWith('#')) {\n let hex = lower.slice(1)\n if (/^[0-9a-f]{3,4}$/.test(hex)) hex = [...hex.slice(0, 3)].map((c) => c + c).join('')\n else if (/^[0-9a-f]{8}$/.test(hex)) hex = hex.slice(0, 6)\n if (!/^[0-9a-f]{6}$/.test(hex)) fail(owner, `color '${s}' is not a valid hex colour - ${HELP}`)\n this.#setHex(parseInt(hex, 16), owner)\n return\n }\n const named = CSS_COLORS.get(lower)\n if (named !== undefined) {\n this.#setHex(named, owner)\n return\n }\n const m = FUNC.exec(s)\n if (!m) fail(owner, `'${s}' is not a colour${didYouMean(lower, CSS_COLORS.keys())} - ${HELP}`)\n const [, fn, a, aUnit, b, bUnit, c, cUnit] = m\n if (fn.toLowerCase().startsWith('rgb')) {\n const channel = (v, unit) => clamp01(unit === '%' ? +v / 100 : +v / 255)\n this.setSRGB(channel(a, aUnit), channel(b, bUnit), channel(c, cUnit))\n } else {\n // hsl: hue in degrees, saturation and lightness in percent\n const h = (((+a % 360) + 360) % 360) / 360\n const sat = clamp01(+b / 100), light = clamp01(+c / 100)\n const q = light < 0.5 ? light * (1 + sat) : light + sat - light * sat\n const p = 2 * light - q\n const hue = (t) => {\n t = (t + 1) % 1\n if (t < 1 / 6) return p + (q - p) * 6 * t\n if (t < 1 / 2) return q\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n return p\n }\n this.setSRGB(hue(h + 1 / 3), hue(h), hue(h - 1 / 3))\n }\n }\n}\n","// Section planes: a node's `clip` cuts away everything in its subtree on one side of a plane, for\n// cutaways - an engine with its block opened up, a building with a wall off. The plane lives in the\n// node's own space, so it moves and turns with the node. Drawing, shadows, picking and the\n// raycaster all leave out what is cut away; a cap colour fills the cut faces of closed shapes - a\n// surface lying on the plane itself, so parts that touch join cleanly and what's inside stays hidden.\nimport { Color } from './value/Color.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { checkNumber, checkOptions, describe, fail } from './validate.js'\n\n/** @import { ColorInput, Vec3Input } from './types.js' */\n/** @import { Node } from './scene/Node.js' */\n\n/**\n * @typedef {object} ClipOptions\n * @property {Vec3Input} [normal] the side of the plane that is cut away, in the node's own space\n * (default [0, 0, 1]: the front, towards a camera that hasn't moved)\n * @property {number} [offset] how far along the normal from the node's origin the plane lies (default 0)\n * @property {ColorInput | null} [cap] fill colour for the cut faces of closed shapes, lit as a flat\n * face on the plane; null leaves them open, showing the inside (default null). Caps need closed\n * solids: an open surface (a plane, an open tube) under a capped clip would fill in wrongly\n */\n\nexport const CLIP_OPTIONS = ['normal', 'offset', 'cap']\nexport const CLIP_HINTS = {\n constant: \"use 'offset' for how far along the normal the plane is\",\n distance: \"use 'offset' for how far along the normal the plane is\",\n plane: \"give the plane as 'normal' and 'offset'\",\n color: \"use 'cap' for the colour of the cut faces\",\n capColor: \"use 'cap' for the colour of the cut faces\",\n}\n\n/** A section plane, as a node's `clip`: change its numbers in place to move the cut. */\nexport class Clip {\n /** Which side is cut away, in the node's space; any length. @type {Vec3} */ normal = new Vec3(0, 0, 1)\n /** How far along the normal from the node's origin the plane is. */ offset = 0\n /** Fill colour for cut faces of closed shapes, or null for none. @type {Color | null} */ cap = null\n\n /** @param {ClipOptions} [options] */\n constructor(options = {}) {\n checkOptions('clip', options, CLIP_OPTIONS, CLIP_HINTS)\n if (options.normal !== undefined) this.normal.copy(options.normal, 'clip')\n if (!(Math.hypot(this.normal[0], this.normal[1], this.normal[2]) > 0)) fail('clip', \"'normal' can't be [0, 0, 0] - it says which side is cut away\")\n if (options.offset !== undefined) this.offset = checkNumber('clip', 'offset', options.offset)\n if (options.cap != null) this.cap = Color.fromInput(options.cap, 'clip')\n }\n\n /** @internal\n * A Clip from a Clip (returned as is) or options.\n * @param {Clip | ClipOptions} input @param {string} [owner]\n * @returns {Clip}\n */\n static fromInput(input, owner = 'clip') {\n if (input instanceof Clip) return input\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n fail(owner, `'clip' must be { normal, offset, cap } or null, got ${describe(input)}`)\n }\n return new Clip(input)\n }\n\n /** @returns {ClipOptions} */\n toJSON() {\n /** @type {ClipOptions} */\n const json = { normal: this.normal.toArray(), offset: this.offset }\n if (this.cap) json.cap = this.cap.getStyle()\n return json\n }\n}\n\n/**\n * The plane of a node's clip in world space, as [nx, ny, nz, d] with a unit normal: a point p is\n * cut away where n.p + d > 0. Uses the node's world matrix as it stands.\n * @param {Node} node a node with a clip\n * @param {Float32Array} [out]\n * @returns {Float32Array}\n */\nexport function worldPlane(node, out = new Float32Array(4)) {\n const clip = /** @type {Clip} */ (node.clip), m = node.worldMatrix\n const [x, y, z] = clip.normal, l = Math.hypot(x, y, z)\n const nx = x / l, ny = y / l, nz = z / l\n // a point on the plane, and the normal through the inverse transpose - as a plane, [n, d] times\n // the inverse world matrix, which for the normal is its cofactors\n const px = nx * clip.offset, py = ny * clip.offset, pz = nz * clip.offset\n const wx = m[0] * px + m[4] * py + m[8] * pz + m[12], wy = m[1] * px + m[5] * py + m[9] * pz + m[13], wz = m[2] * px + m[6] * py + m[10] * pz + m[14]\n const c0 = [m[5] * m[10] - m[6] * m[9], m[6] * m[8] - m[4] * m[10], m[4] * m[9] - m[5] * m[8]]\n const c1 = [m[2] * m[9] - m[1] * m[10], m[0] * m[10] - m[2] * m[8], m[1] * m[8] - m[0] * m[9]]\n const c2 = [m[1] * m[6] - m[2] * m[5], m[2] * m[4] - m[0] * m[6], m[0] * m[5] - m[1] * m[4]]\n let ox = c0[0] * nx + c1[0] * ny + c2[0] * nz, oy = c0[1] * nx + c1[1] * ny + c2[1] * nz, oz = c0[2] * nx + c1[2] * ny + c2[2] * nz\n // a mirroring transform flips the cofactors' sign; keep the normal on the cut-away side\n const det = m[0] * c0[0] + m[4] * c1[0] + m[8] * c2[0]\n const s = (det < 0 ? -1 : 1) / (Math.hypot(ox, oy, oz) || 1)\n ox *= s\n oy *= s\n oz *= s\n out[0] = ox\n out[1] = oy\n out[2] = oz\n out[3] = -(ox * wx + oy * wy + oz * wz)\n return out\n}\n\n/** The nearest node at or above this one with a clip - the one that cuts it - or null. @param {Node | null} node */\nexport function clipOwner(node) {\n for (let n = node; n; n = n.parent) if (n.clip) return n\n return null\n}\n","import { describe, fail } from '../validate.js'\n\n/**\n * Euler angles in radians, applied in XYZ order (three.js's default). A node's `rotation` is an\n * Euler kept in sync with its `quaternion`: `node.rotation.y += 0.01` works as expected.\n */\nexport class Euler {\n #x = 0\n #y = 0\n #z = 0\n\n /** Only XYZ is supported. */\n get order() { return 'XYZ' }\n\n /** @internal Called after any change. @type {(() => void) | null} */\n onChange = null\n\n /** @param {number} [x] @param {number} [y] @param {number} [z] */\n constructor(x = 0, y = 0, z = 0) {\n this.#x = x\n this.#y = y\n this.#z = z\n }\n\n get x() { return this.#x }\n set x(v) { this.#x = v; this.onChange?.() }\n get y() { return this.#y }\n set y(v) { this.#y = v; this.onChange?.() }\n get z() { return this.#z }\n set z(v) { this.#z = v; this.onChange?.() }\n\n /** @param {number} x @param {number} y @param {number} z @returns {this} */\n set(x, y, z) {\n this.#x = x\n this.#y = y\n this.#z = z\n this.onChange?.()\n return this\n }\n\n /** @param {Euler | ArrayLike<number>} e [x, y, z] @param {string} [owner] @returns {this} */\n copy(e, owner = 'Euler') {\n if (e instanceof Euler) return this.set(e.x, e.y, e.z)\n if (!e || typeof e !== 'object' || !(e.length >= 3)) fail(owner, `expected rotation angles [x, y, z] in radians, got ${describe(e)}`)\n return this.set(e[0], e[1], e[2])\n }\n\n /** @returns {Euler} */\n clone() {\n return new Euler(this.#x, this.#y, this.#z)\n }\n\n /**\n * The XYZ angles of a quaternion, without firing onChange (used to sync from a node's quaternion).\n * @param {ArrayLike<number>} q\n * @returns {this}\n */\n setFromQuat(q) {\n const x = q[0], y = q[1], z = q[2], w = q[3]\n // elements of the rotation matrix the angles are read from\n const m11 = 1 - 2 * (y * y + z * z), m12 = 2 * (x * y - z * w), m13 = 2 * (x * z + y * w)\n const m22 = 1 - 2 * (x * x + z * z), m23 = 2 * (y * z - x * w)\n const m32 = 2 * (y * z + x * w), m33 = 1 - 2 * (x * x + y * y)\n this.#y = Math.asin(Math.min(1, Math.max(-1, m13)))\n if (Math.abs(m13) < 0.9999999) {\n this.#x = Math.atan2(-m23, m33)\n this.#z = Math.atan2(-m12, m11)\n } else {\n // gimbal lock: x and z rotate about the same axis\n this.#x = Math.atan2(m32, m22)\n this.#z = 0\n }\n return this\n }\n\n /** @returns {[number, number, number]} */\n toArray() {\n return [this.#x, this.#y, this.#z]\n }\n\n toJSON() {\n return this.toArray()\n }\n\n *[Symbol.iterator]() {\n yield this.#x\n yield this.#y\n yield this.#z\n }\n}\n","// Quaternions as Float32Array(4) [x, y, z, w]. Signatures follow gl-matrix.\n\n/** @returns {Float32Array} identity quaternion */\nexport function create() {\n const out = new Float32Array(4)\n out[3] = 1\n return out\n}\n\n/** @param {number} x @param {number} y @param {number} z @param {number} w @returns {Float32Array} */\nexport function fromValues(x, y, z, w) {\n const out = new Float32Array(4)\n out[0] = x\n out[1] = y\n out[2] = z\n out[3] = w\n return out\n}\n\n/** Rotation of `rad` radians about a normalised axis. @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} axis @param {number} rad @returns {T} */\nexport function setAxisAngle(out, axis, rad) {\n const s = Math.sin(rad * 0.5)\n out[0] = s * axis[0]\n out[1] = s * axis[1]\n out[2] = s * axis[2]\n out[3] = Math.cos(rad * 0.5)\n return out\n}\n\n/** out = a * b (apply b, then a) @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @param {Float32Array | number[]} b @returns {T} */\nexport function multiply(out, a, b) {\n const ax = a[0], ay = a[1], az = a[2], aw = a[3]\n const bx = b[0], by = b[1], bz = b[2], bw = b[3]\n out[0] = ax * bw + aw * bx + ay * bz - az * by\n out[1] = ay * bw + aw * by + az * bx - ax * bz\n out[2] = az * bw + aw * bz + ax * by - ay * bx\n out[3] = aw * bw - ax * bx - ay * by - az * bz\n return out\n}\n\n/** @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @returns {T} */\nexport function normalize(out, a) {\n const x = a[0], y = a[1], z = a[2], w = a[3]\n let len = x * x + y * y + z * z + w * w\n if (len > 0) len = 1 / Math.sqrt(len)\n out[0] = x * len\n out[1] = y * len\n out[2] = z * len\n out[3] = w * len\n return out\n}\n\n/** @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @returns {T} */\nexport function invert(out, a) {\n const x = a[0], y = a[1], z = a[2], w = a[3]\n const dot = x * x + y * y + z * z + w * w\n const inv = dot ? 1 / dot : 0\n out[0] = -x * inv\n out[1] = -y * inv\n out[2] = -z * inv\n out[3] = w * inv\n return out\n}\n\n/** Spherical interpolation, taking the short way round. @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @param {Float32Array | number[]} b @param {number} t @returns {T} */\nexport function slerp(out, a, b, t) {\n const ax = a[0], ay = a[1], az = a[2], aw = a[3]\n let bx = b[0], by = b[1], bz = b[2], bw = b[3]\n let cosom = ax * bx + ay * by + az * bz + aw * bw\n if (cosom < 0) {\n cosom = -cosom\n bx = -bx; by = -by; bz = -bz; bw = -bw\n }\n let s0 = 1 - t, s1 = t\n if (1 - cosom > 0.000001) {\n const omega = Math.acos(cosom), sinom = Math.sin(omega)\n s0 = Math.sin((1 - t) * omega) / sinom\n s1 = Math.sin(t * omega) / sinom\n }\n out[0] = s0 * ax + s1 * bx\n out[1] = s0 * ay + s1 * by\n out[2] = s0 * az + s1 * bz\n out[3] = s0 * aw + s1 * bw\n return out\n}\n\n// Ken Shoemake's algorithm, as in gl-matrix. The matrix must be a pure rotation.\n/** @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} m 3x3 column-major @returns {T} */\nexport function fromMat3(out, m) {\n const trace = m[0] + m[4] + m[8]\n if (trace > 0) {\n let root = Math.sqrt(trace + 1)\n out[3] = 0.5 * root\n root = 0.5 / root\n out[0] = (m[5] - m[7]) * root\n out[1] = (m[6] - m[2]) * root\n out[2] = (m[1] - m[3]) * root\n } else {\n let i = 0\n if (m[4] > m[0]) i = 1\n if (m[8] > m[i * 3 + i]) i = 2\n const j = (i + 1) % 3, k = (i + 2) % 3\n let root = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1)\n out[i] = 0.5 * root\n root = 0.5 / root\n out[3] = (m[j * 3 + k] - m[k * 3 + j]) * root\n out[j] = (m[j * 3 + i] + m[i * 3 + j]) * root\n out[k] = (m[k * 3 + i] + m[i * 3 + k]) * root\n }\n return out\n}\n\n// Euler angles (radians) applied in XYZ order - the same convention as three.js's default.\n/** @template {Float32Array | number[]} T @param {T} out @param {number} x @param {number} y @param {number} z @returns {T} */\nexport function fromEulerXYZ(out, x, y, z) {\n const c1 = Math.cos(x / 2), c2 = Math.cos(y / 2), c3 = Math.cos(z / 2)\n const s1 = Math.sin(x / 2), s2 = Math.sin(y / 2), s3 = Math.sin(z / 2)\n out[0] = s1 * c2 * c3 + c1 * s2 * s3\n out[1] = c1 * s2 * c3 - s1 * c2 * s3\n out[2] = c1 * c2 * s3 + s1 * s2 * c3\n out[3] = c1 * c2 * c3 - s1 * s2 * s3\n return out\n}\n","import * as quat from '../math/quat.js'\nimport { describe, fail } from '../validate.js'\n\n/** @import { QuatInput } from '../types.js' */\n\n/**\n * A rotation quaternion [x, y, z, w]: a Float32Array(4) with accessors and chainable methods.\n * A node's quaternion and its Euler `rotation` keep each other in sync through these setters;\n * writing by index (e.g. passing it as `out` to a quat function) does not, so call `changed()`\n * afterwards when doing that.\n */\nexport class Quat extends Float32Array {\n static get [Symbol.species]() { return Float32Array }\n\n /** @internal Called after any change made through the methods below. @type {(() => void) | null} */\n onChange = null\n\n /** @param {number} [x] @param {number} [y] @param {number} [z] @param {number} [w] */\n constructor(x = 0, y = 0, z = 0, w = 1) {\n super(4)\n this[0] = x\n this[1] = y\n this[2] = z\n this[3] = w\n }\n\n get x() { return this[0] }\n set x(v) { this[0] = v; this.changed() }\n get y() { return this[1] }\n set y(v) { this[1] = v; this.changed() }\n get z() { return this[2] }\n set z(v) { this[2] = v; this.changed() }\n get w() { return this[3] }\n set w(v) { this[3] = v; this.changed() }\n\n /** @internal Notify the owner after editing by index. @returns {this} */\n changed() {\n this.onChange?.()\n return this\n }\n\n /**\n * @overload\n * @param {number} x @param {number} y @param {number} z @param {number} w\n * @returns {this}\n */\n /**\n * @overload\n * @param {ArrayLike<number>} array @param {number} [offset]\n * @returns {void}\n */\n /** @param {number | ArrayLike<number>} x @param {number} [y] @param {number} [z] @param {number} [w] */\n set(x, y, z, w) {\n if (typeof x !== 'number') {\n super.set(x, y ?? 0)\n this.changed()\n return\n }\n this[0] = x\n this[1] = y\n this[2] = z\n this[3] = w\n return this.changed()\n }\n\n /** @param {QuatInput} q [x, y, z, w], or { x, y, z, w } as physics engines give them @param {string} [owner] @returns {this} */\n copy(q, owner = 'Quat') {\n const o = /** @type {any} */ (q)\n if (o && typeof o === 'object' && o.length >= 4) {\n this[0] = o[0]\n this[1] = o[1]\n this[2] = o[2]\n this[3] = o[3]\n } else if (o && typeof o === 'object' && 'x' in o && 'y' in o && 'z' in o && 'w' in o) {\n this[0] = o.x\n this[1] = o.y\n this[2] = o.z\n this[3] = o.w\n } else fail(owner, `expected a quaternion [x, y, z, w] or { x, y, z, w }, got ${describe(q)}`)\n return this.changed()\n }\n\n /** @returns {Quat} */\n clone() {\n return new Quat(this[0], this[1], this[2], this[3])\n }\n\n /** @returns {this} */\n identity() {\n return this.set(0, 0, 0, 1)\n }\n\n /** Euler angles in radians, XYZ order. @param {number} x @param {number} y @param {number} z @returns {this} */\n setFromEuler(x, y, z) {\n quat.fromEulerXYZ(this, x, y, z)\n return this.changed()\n }\n\n /** @param {ArrayLike<number>} axis normalised @param {number} rad @returns {this} */\n setFromAxisAngle(axis, rad) {\n quat.setAxisAngle(this, /** @type {number[]} */ (axis), rad)\n return this.changed()\n }\n\n /** this = this * q (rotate by q in the local frame) @param {ArrayLike<number>} q @returns {this} */\n multiply(q) {\n quat.multiply(this, this, /** @type {number[]} */ (q))\n return this.changed()\n }\n\n /** this = q * this (rotate by q in the parent frame) @param {ArrayLike<number>} q @returns {this} */\n premultiply(q) {\n quat.multiply(this, /** @type {number[]} */ (q), this)\n return this.changed()\n }\n\n /** @returns {this} */\n normalize() {\n quat.normalize(this, this)\n return this.changed()\n }\n\n /** @returns {this} */\n invert() {\n quat.invert(this, this)\n return this.changed()\n }\n\n /** @param {ArrayLike<number>} q @param {number} t @returns {this} */\n slerp(q, t) {\n quat.slerp(this, this, /** @type {number[]} */ (q), t)\n return this.changed()\n }\n\n /** @returns {[number, number, number, number]} */\n toArray() {\n return [this[0], this[1], this[2], this[3]]\n }\n\n toJSON() {\n return this.toArray()\n }\n}\n","import { Box3 } from '../value/Box3.js'\nimport { checkOptions, describe, fail } from '../validate.js'\n\n/**\n * @typedef {object} GeometryOptions\n * @property {ArrayLike<number>} positions xyz per vertex\n * @property {ArrayLike<number>} [normals] xyz per vertex; computed (smooth) when missing\n * @property {ArrayLike<number>} [uvs] uv per vertex - glTF convention, (0, 0) is the image's top left\n * @property {ArrayLike<number>} [uvs2] a second uv per vertex, for maps that need every surface on its own\n * patch of texture - baked occlusion and light maps (a texture's uvSet: 1 reads it)\n * @property {ArrayLike<number>} [colors] rgb per vertex, sRGB 0-1 like every colour input\n * @property {ArrayLike<number>} [sizes] points: one per vertex, a multiple of the material's size\n * @property {ArrayLike<number>} [opacities] points: one per vertex, 0-1, multiplying the material's opacity\n * @property {ArrayLike<number>} [angles] points: one per vertex, radians anticlockwise on screen - turns\n * each point's texture\n * @property {ArrayLike<number>} [indices] vertex indices; triangles for meshes, pairs for lines\n */\n\nconst OPTIONS = ['positions', 'normals', 'uvs', 'uvs2', 'colors', 'sizes', 'opacities', 'angles', 'indices']\n// the per-point arrays: Points with any of them draw each point as its own square, sized, faded and turned\nconst POINT_ARRAYS = /** @type {const} */ (['sizes', 'opacities', 'angles'])\n\n/**\n * Vertex data: flat typed arrays plus an optional index. Generators such as box() and sphere()\n * return one; build your own from arrays. Change the arrays in place and call needsUpdate().\n */\nexport class Geometry {\n /** The options it takes. */\n static OPTIONS = OPTIONS\n /** @type {Float32Array} */ positions\n /** @type {Float32Array | null} */ uvs = null\n /** A second UV set, for baked occlusion and light maps. @type {Float32Array | null} */ uvs2 = null\n /** @type {Float32Array | null} */ colors = null\n /** Points: each one's size, as a multiple of the material's. @type {Float32Array | null} */ sizes = null\n /** Points: each one's opacity, 0-1, times the material's. @type {Float32Array | null} */ opacities = null\n /** Points: each one's turn on screen, in radians anticlockwise. @type {Float32Array | null} */ angles = null\n /** @type {Uint16Array | Uint32Array | null} */ indices = null\n\n /** @internal Bumped by needsUpdate() so renderers know to re-upload. */\n version = 0\n\n /**\n * Draw only the first `drawCount` vertices (indices, when indexed), or all of them when null -\n * for geometry that fills up over time, such as particles. Picking honours it too.\n * @type {number | null}\n */\n drawCount = null\n\n /**\n * How this geometry was made, when it came from a generator - lets toJSON() stay small.\n * @type {{ type: string } & Record<string, unknown> | null}\n */\n source = null\n\n /** @type {Float32Array | null} */\n #normals = null\n /** The normals were worked out on first read, rather than given or asked for: they follow the shape. */\n #autoNormals = false\n /** @type {Box3 | null} */\n #bounds = null\n /** @type {Set<() => void>} */\n #onDispose = new Set()\n\n /** @param {GeometryOptions} options */\n constructor(options) {\n checkOptions('Geometry', options, OPTIONS)\n if (!options?.positions) fail('Geometry', \"'positions' is required - an array of x, y, z per vertex\")\n this.positions = toFloat32('positions', options.positions, 3)\n const n = this.vertexCount\n if (options.normals) this.#normals = toFloat32('normals', options.normals, 3, n)\n if (options.uvs) this.uvs = toFloat32('uvs', options.uvs, 2, n)\n if (options.uvs2) this.uvs2 = toFloat32('uvs2', options.uvs2, 2, n)\n if (options.colors) this.colors = toFloat32('colors', options.colors, 3, n)\n for (const name of POINT_ARRAYS) if (options[name]) this[name] = toFloat32(name, options[name], 1, n)\n if (options.indices) {\n // -1: no indices at all refer to no vertex, so an empty geometry can say so\n let max = -1\n for (let i = 0; i < options.indices.length; i++) {\n const v = options.indices[i]\n if (!Number.isInteger(v) || v < 0) fail('Geometry', `'indices' must be whole numbers 0 or more, found ${describe(v)} at ${i}`)\n if (v > max) max = v\n }\n if (max >= n) fail('Geometry', `'indices' refers to vertex ${max} but there are only ${n} vertices`)\n this.indices = n > 65535 ? Uint32Array.from(options.indices) : Uint16Array.from(options.indices)\n }\n }\n\n /**\n * xyz per vertex. Computed (smooth) from the triangles on first read when not supplied, so\n * points and lines - whose geometry has no triangles - never pay for them - and computed again after\n * needsUpdate(), so they follow positions edited in place. Normals that were supplied, assigned or\n * made by calling computeNormals() are kept as they are.\n * @type {Float32Array}\n */\n get normals() {\n if (!this.#normals) {\n this.computeNormals()\n this.#autoNormals = true\n }\n return /** @type {Float32Array} */ (this.#normals)\n }\n\n set normals(v) {\n this.#normals = v\n this.#autoNormals = false\n }\n\n /** True once normals exist, supplied or computed. */\n get hasNormals() {\n return this.#normals !== null\n }\n\n /** @returns {number} */\n get vertexCount() {\n return this.positions.length / 3\n }\n\n /** Number of indices if indexed, otherwise vertices. @returns {number} */\n get elementCount() {\n return this.indices ? this.indices.length : this.vertexCount\n }\n\n /** The elements actually drawn: elementCount, limited by drawCount. @returns {number} */\n get drawnCount() {\n return this.drawCount === null ? this.elementCount : Math.max(0, Math.min(this.drawCount, this.elementCount))\n }\n\n /**\n * The vertices actually drawn as points: vertexCount, limited by drawCount. Points draw each vertex\n * once and ignore the index, so a mesh's indexed geometry can be shown as its vertices too.\n * @returns {number}\n */\n get drawnVertices() {\n return this.drawCount === null ? this.vertexCount : Math.max(0, Math.min(this.drawCount, this.vertexCount))\n }\n\n /** Local space bounds, cached until needsUpdate(). @returns {Box3} */\n get bounds() {\n return this.#bounds ??= new Box3().expandByPositions(this.positions)\n }\n\n /**\n * Call after editing the arrays in place. It is no longer what its generator made, so toJSON() saves\n * the arrays; normals that were worked out on first read are worked out again on the next.\n * @returns {this}\n */\n needsUpdate() {\n this.source = null\n if (this.#autoNormals) this.#normals = null\n return this.#changed()\n }\n\n #changed() {\n this.version++\n this.#bounds = null\n return this\n }\n\n /**\n * Compute vertex normals from the triangles. Smooth normals average the faces sharing each vertex;\n * flat normals give every face its own vertices (a faceted look), so indexed geometry becomes\n * non-indexed. Non-indexed geometry is assumed to already have its own vertices per triangle.\n * @param {{ flat?: boolean }} [options]\n * @returns {this}\n */\n computeNormals({ flat = false } = {}) {\n if (flat && this.indices) this.#unweld()\n const p = this.positions\n const normals = new Float32Array(p.length)\n const triangles = this.elementCount - (this.elementCount % 3)\n for (let t = 0; t < triangles; t += 3) {\n const a = this.#index(t), b = this.#index(t + 1), c = this.#index(t + 2)\n // face normal (b - a) x (c - a), unnormalised so larger faces weigh more\n const abx = p[b * 3] - p[a * 3], aby = p[b * 3 + 1] - p[a * 3 + 1], abz = p[b * 3 + 2] - p[a * 3 + 2]\n const acx = p[c * 3] - p[a * 3], acy = p[c * 3 + 1] - p[a * 3 + 1], acz = p[c * 3 + 2] - p[a * 3 + 2]\n const nx = aby * acz - abz * acy, ny = abz * acx - abx * acz, nz = abx * acy - aby * acx\n for (const v of [a, b, c]) {\n normals[v * 3] += nx\n normals[v * 3 + 1] += ny\n normals[v * 3 + 2] += nz\n }\n }\n for (let i = 0; i < normals.length; i += 3) {\n const len = Math.hypot(normals[i], normals[i + 1], normals[i + 2])\n if (len > 0) {\n normals[i] /= len\n normals[i + 1] /= len\n normals[i + 2] /= len\n }\n }\n this.normals = normals\n // normals follow from the positions, which a generator would make again: it is still its shape\n return this.#changed()\n }\n\n /** A copy with its own arrays. @returns {Geometry} */\n clone() {\n const g = new Geometry({\n positions: this.positions,\n normals: this.#normals ?? undefined,\n uvs: this.uvs ?? undefined,\n uvs2: this.uvs2 ?? undefined,\n colors: this.colors ?? undefined,\n sizes: this.sizes ?? undefined,\n opacities: this.opacities ?? undefined,\n angles: this.angles ?? undefined,\n indices: this.indices ?? undefined,\n })\n g.source = this.source && { ...this.source }\n g.drawCount = this.drawCount\n return g\n }\n\n /** Release GPU resources made from this geometry. It can still be used; it is re-uploaded on next render. */\n dispose() {\n for (const fn of this.#onDispose) fn()\n }\n\n /** @internal For renderers: called when dispose() is. Returns an unsubscribe function. @param {() => void} fn */\n onDispose(fn) {\n this.#onDispose.add(fn)\n return () => this.#onDispose.delete(fn)\n }\n\n /** A generator description when made by one, otherwise the raw arrays. */\n toJSON() {\n if (this.source) return { ...this.source }\n /** @type {Record<string, number[]>} */\n const json = { positions: Array.from(this.positions) }\n if (this.#normals) json.normals = Array.from(this.#normals)\n if (this.uvs) json.uvs = Array.from(this.uvs)\n if (this.uvs2) json.uvs2 = Array.from(this.uvs2)\n if (this.colors) json.colors = Array.from(this.colors)\n for (const name of POINT_ARRAYS) if (this[name]) json[name] = Array.from(/** @type {Float32Array} */ (this[name]))\n if (this.indices) json.indices = Array.from(this.indices)\n return json\n }\n\n /** @param {number} i */\n #index(i) {\n return this.indices ? this.indices[i] : i\n }\n\n // Expand indexed vertices so no two triangles share one.\n #unweld() {\n const idx = /** @type {Uint16Array | Uint32Array} */ (this.indices)\n const expand = (src, size) => {\n if (!src) return null\n const out = new Float32Array(idx.length * size)\n for (let i = 0; i < idx.length; i++) {\n for (let k = 0; k < size; k++) out[i * size + k] = src[idx[i] * size + k]\n }\n return out\n }\n this.positions = /** @type {Float32Array} */ (expand(this.positions, 3))\n this.uvs = expand(this.uvs, 2)\n this.uvs2 = expand(this.uvs2, 2)\n this.colors = expand(this.colors, 3)\n for (const name of POINT_ARRAYS) this[name] = expand(this[name], 1)\n this.indices = null\n this.source = null\n }\n}\n\n/**\n * @param {string} name @param {ArrayLike<number>} values @param {number} size per vertex\n * @param {number} [count] expected vertex count\n * @returns {Float32Array}\n */\nfunction toFloat32(name, values, size, count) {\n if (!values || typeof values !== 'object' || typeof values.length !== 'number') {\n fail('Geometry', `'${name}' must be an array of numbers, got ${describe(values)}`)\n }\n if (values.length % size !== 0) fail('Geometry', `'${name}' has ${values.length} numbers - expected ${size} per vertex`)\n if (count !== undefined && values.length !== count * size) {\n fail('Geometry', `'${name}' has ${values.length / size} entries but 'positions' has ${count} vertices`)\n }\n const out = Float32Array.from(values)\n for (let i = 0; i < out.length; i++) {\n if (Number.isNaN(out[i])) fail('Geometry', `'${name}' contains a non-number at index ${i}`)\n }\n return out\n}\n","import { checkNumber, checkOneOf, checkOptions, describe, fail } from '../validate.js'\n\n/**\n * Raw pixels, RGBA, top row first: bytes for ordinary images, floats for HDR (linear radiance).\n * @typedef {{ data: Uint8Array | Float32Array, width: number, height: number }} DataImage\n */\n/** @typedef {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap | OffscreenCanvas | DataImage} TextureImage */\n\n/**\n * @typedef {object} TextureOptions\n * @property {TextureImage} [image] the pixels; omit and give a url to load them\n * @property {string} [url] image to load (starts loading immediately in a browser); a .hdr file loads as\n * linear HDR radiance, for scene.environment; a video (.mp4, .webm, .ogv, .mov, .m4v) plays muted and on a\n * loop, and texture.image is its <video> to pause, seek or unmute\n * @property {'srgb' | 'linear'} [colorSpace] 'srgb' for colour maps (default), 'linear' for data\n * maps such as normal and roughness maps\n * @property {'repeat' | 'clamp' | 'mirror'} [wrap] (default 'repeat')\n * @property {number[]} [repeat] [u, v] (default [1, 1])\n * @property {number[]} [offset] [u, v] (default [0, 0])\n * @property {number} [rotation] turns the image on the surface, in radians, about `center` (default 0)\n * @property {number[]} [center] [u, v] the point rotation turns about, in repeated UVs (default [0, 0], the\n * corner, as glTF has it; [0.5, 0.5] for the middle of an unrepeated image)\n * @property {0 | 1} [uvSet] which UV set to read: 0 the first, 1 the second (Geometry uvs2) - baked occlusion\n * and light maps usually come on the second (default 0)\n * @property {'linear' | 'nearest'} [filter] (default 'linear')\n * @property {boolean} [mipmaps] (default true; false for a video, which would make them every frame)\n * @property {number} [anisotropy] samples along a surface seen at a glancing angle - floors and roads\n * stay sharp into the distance. Up to what the GPU allows; 1 is off (default 8)\n * @property {boolean} [flipY] flip on upload; false for glTF-style UVs (default false)\n */\n\nconst OPTIONS = ['image', 'url', 'colorSpace', 'wrap', 'repeat', 'offset', 'rotation', 'center', 'uvSet', 'filter', 'mipmaps', 'anisotropy', 'flipY']\nconst DEFAULTS = { colorSpace: 'srgb', wrap: 'repeat', repeat: [1, 1], offset: [0, 0], rotation: 0, center: [0, 0], uvSet: 0, filter: 'linear',\n mipmaps: true, anisotropy: 8, flipY: false }\n\nconst HINTS = {\n src: \"use 'url' for the image address\",\n encoding: \"use colorSpace: 'srgb' | 'linear'\",\n wrapS: \"use wrap: 'repeat' | 'clamp' | 'mirror' (applies to both directions)\",\n maxAnisotropy: \"use 'anisotropy' - samples along glancing angles, 1 for off\",\n channel: \"use 'uvSet' - 0 for the first UV set, 1 for the second\",\n texCoord: \"use 'uvSet' - 0 for the first UV set, 1 for the second\",\n scale: \"use 'repeat' - [u, v] times across\",\n}\n\n/**\n * Part of an image, in its pixels from the top left, as needsUpdate() takes it.\n * @typedef {{ x: number, y: number, width: number, height: number }} TextureRegion\n */\n\n// how many updates a texture remembers the region of, for a renderer catching up on several - a\n// frame of paint can make a hundred or so\nconst CHANGES_KEPT = 256\n\n/**\n * An image for a material map. A video's frames upload by themselves as it plays; after drawing on\n * a canvas, call `needsUpdate()` - with the rectangle drawn in, to send only that.\n */\nexport class Texture {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n /** @type {TextureImage | null} */\n #image = null\n /** @type {string | null} */\n url = null\n /** @type {'srgb' | 'linear'} */\n #colorSpace = 'srgb'\n /** set by the app, rather than left to its default - a material's data slot leaves it alone then */\n #colorSpaceSet = false\n /** @type {'repeat' | 'clamp' | 'mirror'} */\n wrap = 'repeat'\n repeat = [1, 1]\n offset = [0, 0]\n /** Turns the image on the surface, in radians, about `center`. */\n rotation = 0\n /** [u, v] the point rotation turns about, in repeated UVs. */\n center = [0, 0]\n /** Which UV set it reads: 0 the first, 1 the second (Geometry uvs2). @type {0 | 1} */\n uvSet = 0\n /** @type {'linear' | 'nearest'} */\n filter = 'linear'\n mipmaps = true\n /** Samples along glancing angles, up to the GPU's limit; 1 is off. Call needsUpdate() after changing it. */\n anisotropy = 8\n flipY = false\n /** @internal Bumped by needsUpdate() so renderers re-upload. */\n version = 0\n /** What each recent update changed - its region, or null for all of it. @type {{ version: number, region: TextureRegion | null }[]} */\n #changes = []\n /** Resolves when the image is available (immediately when one was given). @type {Promise<Texture>} */\n ready\n\n /** @type {Set<() => void>} */\n #onDispose = new Set()\n\n /** @param {TextureOptions | string} [options] options, or just a url */\n constructor(options = {}) {\n if (typeof options === 'string') options = { url: options }\n checkOptions('Texture', options, OPTIONS, HINTS)\n const o = { ...DEFAULTS, ...options }\n this.#colorSpace = checkOneOf('Texture', 'colorSpace', o.colorSpace, ['srgb', 'linear'])\n this.#colorSpaceSet = options.colorSpace !== undefined\n this.wrap = checkOneOf('Texture', 'wrap', o.wrap, ['repeat', 'clamp', 'mirror'])\n this.filter = checkOneOf('Texture', 'filter', o.filter, ['linear', 'nearest'])\n this.repeat = pair('repeat', o.repeat)\n this.offset = pair('offset', o.offset)\n this.rotation = checkNumber('Texture', 'rotation', o.rotation)\n this.center = pair('center', o.center)\n if (o.uvSet !== 0 && o.uvSet !== 1) fail('Texture', `'uvSet' is 0 (the first UV set) or 1 (the second), got ${describe(o.uvSet)}`)\n this.uvSet = o.uvSet\n // a video would make mipmaps every frame: off unless asked for\n this.mipmaps = options.mipmaps !== undefined ? !!options.mipmaps : !(isVideo(o.image) || (!o.image && VIDEO.test(o.url ?? '')))\n this.anisotropy = checkNumber('Texture', 'anisotropy', o.anisotropy)\n if (!(this.anisotropy >= 1)) fail('Texture', `'anisotropy' is how many samples along a glancing angle - 1 (off) or more, got ${this.anisotropy}`)\n this.flipY = !!o.flipY\n this.url = o.url ?? null\n\n if (o.image) {\n this.image = o.image\n this.ready = isVideo(o.image) ? loaded(/** @type {HTMLVideoElement} */ (o.image)).then(() => this) : Promise.resolve(this)\n this.ready.catch(() => {})\n } else if (this.url) {\n this.ready = this.#load(this.url)\n // a failed load is reported by whoever awaits `ready`; don't also raise an unhandled rejection\n this.ready.catch(() => {})\n } else {\n fail('Texture', \"needs an 'image' or a 'url'\")\n }\n }\n\n /** Call after redrawing a canvas or advancing a video. @returns {this} */\n /**\n * The pixels: null until loaded. A <video>'s frames upload by themselves while it plays.\n * @returns {TextureImage | null}\n */\n get image() { return this.#image }\n /** @param {TextureImage | null} v */\n set image(v) {\n this.#image = v\n this.needsUpdate()\n if (isVideo(v)) this.#follow(/** @type {HTMLVideoElement} */ (v))\n }\n\n // Each new frame of a playing video marks the texture changed, so views redraw with it: the\n // browser's own per-frame callback where there is one, otherwise a check every animation frame\n // while it plays. Following stops when the image is replaced.\n /** @param {HTMLVideoElement} video */\n #follow(video) {\n if (typeof video.requestVideoFrameCallback === 'function') {\n const frame = () => {\n if (this.#image !== video) return\n this.needsUpdate()\n video.requestVideoFrameCallback(frame)\n }\n video.requestVideoFrameCallback(frame)\n return\n }\n let last = -1, running = false\n const tick = () => {\n if (this.#image !== video || video.paused || video.ended) {\n running = false\n return\n }\n if (video.currentTime !== last) {\n last = video.currentTime\n this.needsUpdate()\n }\n requestAnimationFrame(tick)\n }\n const start = () => {\n if (running || this.#image !== video) return\n running = true\n requestAnimationFrame(tick)\n }\n video.addEventListener('play', start)\n // a seek while paused shows a new frame too\n video.addEventListener('seeked', () => {\n if (this.#image === video) this.needsUpdate()\n })\n if (!video.paused) start()\n }\n\n /** 'srgb' for colour (decoded to linear by the GPU), 'linear' for data such as normals and roughness. Call needsUpdate() after changing it. @returns {'srgb' | 'linear'} */\n get colorSpace() { return this.#colorSpace }\n set colorSpace(v) {\n this.#colorSpace = checkOneOf('Texture', 'colorSpace', v, ['srgb', 'linear'])\n this.#colorSpaceSet = true\n }\n\n /** @internal Whether the app chose the colour space, rather than leaving the default. @returns {boolean} */\n get colorSpaceSet() { return this.#colorSpaceSet }\n\n /**\n * Upload the image again, after drawing on it (a canvas) or changing its pixels. Give the\n * rectangle that changed - in the image's pixels, from its top left - and only that is sent: for a\n * big canvas drawn on a little at a time, far less to send each frame.\n *\n * ctx.fillRect(x, y, 20, 20)\n * texture.needsUpdate({ x, y, width: 20, height: 20 })\n * @param {TextureRegion} [region]\n * @returns {this}\n */\n needsUpdate(region) {\n /** @type {TextureRegion | null} */\n let changed = null\n if (region !== undefined) {\n const { x, y, width, height } = region ?? /** @type {any} */ ({})\n if (![x, y, width, height].every((v) => typeof v === 'number' && Number.isFinite(v)) || width < 0 || height < 0) {\n fail('Texture', `needsUpdate() takes the region changed, { x, y, width, height } in the image's pixels, got ${describe(region)}`)\n }\n // whole pixels, covering every one the region touches\n const x0 = Math.floor(x), y0 = Math.floor(y)\n changed = { x: x0, y: y0, width: Math.ceil(x + width) - x0, height: Math.ceil(y + height) - y0 }\n }\n this.version++\n this.#changes.push({ version: this.version, region: changed })\n if (this.#changes.length > CHANGES_KEPT) this.#changes.shift()\n return this\n }\n\n /**\n * @internal What changed since a version a renderer uploaded: each update's region since, or null\n * when that's all of it - an update without a region, or one too long ago to know.\n * @param {number} version\n * @returns {TextureRegion[] | null}\n */\n changedSince(version) {\n const first = this.#changes[0]\n if (!first || first.version > version + 1) return null\n /** @type {TextureRegion[]} */\n const regions = []\n for (const { version: v, region } of this.#changes) {\n if (v <= version) continue\n if (!region) return null\n regions.push(region)\n }\n return regions.length ? regions : null\n }\n\n /** Release the GPU copy. @returns {void} */\n dispose() {\n for (const fn of this.#onDispose) fn()\n }\n\n /** @internal For renderers. Returns an unsubscribe function. @param {() => void} fn */\n onDispose(fn) {\n this.#onDispose.add(fn)\n return () => this.#onDispose.delete(fn)\n }\n\n /** A description (url plus options that differ from the defaults), or null for an in-memory image. */\n toJSON() {\n if (!this.url) return null\n /** @type {Record<string, unknown>} */\n const json = { url: this.url }\n for (const [key, value] of Object.entries(DEFAULTS)) {\n const current = this[/** @type {keyof typeof DEFAULTS} */ (key)]\n if (JSON.stringify(current) !== JSON.stringify(value)) json[key] = current\n }\n return json\n }\n\n /** HDR radiance rather than display colours - floats, tone mapped when drawn. @returns {boolean} */\n get isHDR() {\n return !!this.image && 'data' in this.image && this.image.data instanceof Float32Array\n }\n\n /** @param {string} url @returns {Promise<Texture>} */\n async #load(url) {\n if (VIDEO.test(url)) {\n if (typeof document === 'undefined') throw new Error(`Texture: can't load '${url}' - no video support in this environment`)\n const video = document.createElement('video')\n // muted, so browsers let it play by itself; inline, so phones don't take it full screen\n Object.assign(video, { crossOrigin: 'anonymous', muted: true, loop: true, playsInline: true, autoplay: true, src: url })\n try {\n await loaded(video)\n } catch {\n throw new Error(`Texture: failed to load '${url}'`)\n }\n // a browser that won't autoplay leaves it paused on its first frame: video.play() on a click starts it\n video.play()?.catch(() => {})\n this.image = video\n return this\n }\n if (/\\.hdr($|[?#])/i.test(url)) {\n const [{ parseHDR }, response] = await Promise.all([import('../hdr.js'), fetch(url)])\n if (!response.ok) throw new Error(`Texture: failed to load '${url}' (${response.status})`)\n this.image = parseHDR(await response.arrayBuffer())\n this.colorSpace = 'linear'\n return this\n }\n if (typeof Image === 'undefined') {\n throw new Error(`Texture: can't load '${url}' - no Image support in this environment`)\n }\n const img = new Image()\n img.crossOrigin = 'anonymous'\n img.src = url\n try {\n await img.decode()\n } catch {\n throw new Error(`Texture: failed to load '${url}'`)\n }\n this.image = img\n return this\n }\n}\n\nconst VIDEO = /\\.(mp4|webm|ogv|mov|m4v)($|[?#])/i\n\n/** @internal A <video>, whose frames change as it plays. @param {unknown} image @returns {boolean} */\nexport function isVideo(image) {\n return typeof HTMLVideoElement !== 'undefined' && image instanceof HTMLVideoElement\n}\n\n/** Resolves once a video has a frame to show. @param {HTMLVideoElement} video @returns {Promise<void>} */\nfunction loaded(video) {\n if (video.readyState >= 2) return Promise.resolve()\n return new Promise((resolve, reject) => {\n video.addEventListener('loadeddata', () => resolve(), { once: true })\n video.addEventListener('error', () => reject(new Error('Texture: the video failed to load')), { once: true })\n })\n}\n\n/**\n * Load an image as a texture; resolves once it has decoded.\n * @param {string} url\n * @param {Omit<TextureOptions, 'url' | 'image'>} [options]\n * @returns {Promise<Texture>}\n */\nexport function loadTexture(url, options = {}) {\n return new Texture({ ...options, url }).ready\n}\n\n/** @param {string} name @param {unknown} v @returns {number[]} */\nfunction pair(name, v) {\n if (!Array.isArray(v) || v.length !== 2 || v.some((n) => typeof n !== 'number')) {\n fail('Texture', `'${name}' must be [u, v], got ${describe(v)}`)\n }\n return [v[0], v[1]]\n}\n","import { Color } from '../value/Color.js'\nimport { checkNumber, checkOneOf, checkOptions, describe, fail, warnOnce } from '../validate.js'\nimport { Texture } from './Texture.js'\n\n/** @import { ColorInput } from '../types.js' */\n/** @import { TextureOptions } from './Texture.js' */\n\n/** A map: a Texture, its options, or just a url. @typedef {Texture | TextureOptions | string} MapInput */\n\n/**\n * A shader uniform's value: a number (float), two to four numbers (vec2-vec4), a colour - a colour\n * string or Color, sent linear as the shader works (vec3) - or a Texture (sampler2D).\n * @typedef {number | number[] | ColorInput | Texture} ShaderUniform\n */\n\n/**\n * Small pieces of GLSL run inside phoria2's own shader, so lighting, shadows, fog, clipping,\n * picking and outlines keep working. Every hook can read `uTime` (the View's clock, in seconds)\n * and the uniforms given, and call - p a vec2 or vec3, every result 0-1 - `hash(x)` (the same on every\n * GPU for the same bits), `vnoise(p)` (value noise), `snoise(p)` (simplex noise; `snoised(p)` with its\n * gradient), and `vfbm(p)` / `sfbm(p)` / `sfbmd(p)` (octaves of either, five unless given:\n * `sfbm(p, 8)`), `voronoi(p)` (cellular noise: vec3 of the nearest and second nearest distances and\n * a random 0-1 for the nearest cell); and `srgb(c)` (a colour as picked to linear), `hsv2rgb`, `palette` (cosine\n * palettes, linear), `fresnel(normal, position, power)` (rim light - `cameraPosition` is there too),\n * `rotate2(a)` / `rotate3(axis, a)` matrices, `remap` and `saturate`.\n * @typedef {object} ShaderHooks\n * @property {string} [vertex] runs on each vertex before it is placed: change `local` (vec3, the\n * geometry's own space) - and for meshes `n`, its normal; reads `uv` (meshes), `index` (the\n * instance, point or segment), `size` (points: change it too) and `along` (lines: 0 at a\n * segment's start, 1 at its end)\n * @property {string} [fragment] runs on each pixel before lighting: change `base` (vec4: linear\n * colour and alpha) and, on meshes, `emissive` and `normal` (the shading normal, world space - bend it for\n * relief lit per pixel); `discard` cuts the pixel away - shadows and\n * picking too. Reads `vUv`, `vWorldPosition`, `vNormal` (meshes), `pointUv` and `index`\n * (points), `distance` along the line and `index` the segment (lines)\n * @property {string} [lit] runs after lighting: change `color` (vec3, linear) and `base.a` - glows,\n * scanlines and fades the light doesn't touch\n * @property {Record<string, ShaderUniform>} [uniforms] values the hooks read, by name; change them on\n * `material.shader.uniforms` and the View redraws\n * @property {number} [bounds] how far, in world units, the vertex hook can move a vertex: bounds are\n * padded by it for culling, framing and shadows. Without it a vertex hook turns frustum culling off\n */\n\n/**\n * @typedef {object} MaterialOptions\n * @property {string} [name]\n * @property {ColorInput} [color] base colour (default white)\n * @property {MapInput | null} [map] colour texture\n * @property {number} [opacity] 0-1; below 1 renders in the transparent pass (default 1)\n * @property {boolean} [transparent] blend at any opacity - for maps with soft alpha edges (default: opacity below 1)\n * @property {number} [alphaTest] 0-1: drop pixels whose alpha is below it - cut-outs such as leaves (default 0)\n * @property {number} [roughness] 0 = mirror, 1 = matte (default 0.5)\n * @property {number} [metalness] 0-1 (default 0)\n * @property {MapInput | null} [roughnessMap] multiplies roughness by its green channel (glTF)\n * @property {MapInput | null} [metalnessMap] multiplies metalness by its blue channel (glTF)\n * @property {MapInput | null} [normalMap] tangent-space normals, +Y up (glTF/OpenGL convention)\n * @property {number} [normalScale] strength of the normal map (default 1)\n * @property {MapInput | null} [bumpMap] heights in its red channel, shown as bumps - for height textures and ones\n * drawn in code, with no need to make a normal map\n * @property {number} [bumpScale] how high a height of 1 stands, in the mesh's own units (default 1)\n * @property {number} [triplanar] project the maps onto the mesh from its three axes instead of using UVs -\n * for scans and CAD models, which have none. The number is how many times a map repeats per unit of the\n * mesh's own space; the maps stay on the mesh as it moves. 0 (the default) uses the UVs\n * @property {MapInput | null} [aoMap] ambient occlusion in its red channel; darkens environment and ambient light\n * @property {number} [aoMapIntensity] 0-1 (default 1)\n * @property {MapInput | null} [emissiveMap] multiplies the emissive colour\n * @property {MapInput | null} [lightMap] light baked into a texture, added as light from all round - usually on\n * the second UV set (uvSet: 1)\n * @property {number} [lightMapIntensity] (default 1)\n * @property {number} [environmentIntensity] this material's share of the environment's light and reflections:\n * lower for a matte floor in a shiny showroom, higher to make one thing catch the light (default 1)\n * @property {ColorInput} [emissive] glow colour (default black)\n * @property {number} [emissiveIntensity] (default 1)\n * @property {number} [transmission] 0-1: how much light passes through, as through glass (default 0). Unlike\n * opacity, which fades the whole surface, glass keeps its reflections, and shows less of what is behind it\n * towards its edges. Its colour shows in proportion to 1 - transmission\n * @property {number} [clearcoat] 0-1: a clear glossy layer over the surface - car paint, lacquer, varnish (default 0)\n * @property {number} [clearcoatRoughness] 0-1: how glossy the coat is, 0 a mirror (default 0)\n * @property {number} [sheen] 0-1: the soft bright rim of cloth at grazing angles - velvet, felt, upholstery (default 0)\n * @property {ColorInput} [sheenColor] the sheen's colour (default white)\n * @property {number} [sheenRoughness] 0-1: a thin bright rim at 0, a broad soft glow at 1 (default 0.5)\n * @property {number} [ior] index of refraction, 1 or more: how strongly a non-metal reflects - water 1.33, glass and\n * plastic 1.5 (the default), diamond 2.4\n * @property {number} [specularIntensity] 0-1: scales a non-metal's reflections, 0 for none - chalk, clay (default 1)\n * @property {ColorInput} [specularColor] tints a non-metal's reflections face on (default white)\n * @property {number} [anisotropy] 0-1: brushed metal - highlights drawn out along the brushing, which runs along\n * the UVs' u (around the mesh where it has no UVs) (default 0)\n * @property {number} [anisotropyRotation] turns the brushing from the UVs' u, in radians (default 0)\n * @property {number} [translucency] 0-1: light through thin surfaces, lighting them from behind - leaves, paper,\n * lampshades, curtains (default 0)\n * @property {ColorInput} [translucencyColor] tints the light that comes through (default white)\n * @property {MapInput | null} [matcap] a picture of a lit sphere that gives the whole look - clay, wax, chrome,\n * a painted ball - picked by which way the surface faces the camera. Lights, shadows and the environment are\n * ignored; the colour and colour map multiply it\n * @property {number} [toon] cartoon shading in this many flat tones (2 or more) with a hard-edged highlight;\n * 0 (the default) is smooth\n * @property {boolean} [unlit] flat colour that ignores lights (default false)\n * @property {boolean} [flatShading] faceted look from face normals (default false)\n * @property {boolean} [doubleSided] draw back faces too (default false)\n * @property {boolean} [vertexColors] multiply by the geometry's colors (default false)\n * @property {boolean} [fog] fade into the scene's fog with distance (default true) - false for a sky or a far backdrop\n * @property {'normal' | 'additive' | 'multiply'} [blending] how it combines with what is behind it: 'additive' adds\n * light (glows, sparks), 'multiply' darkens it as a filter does - cyan over magenta is blue (default 'normal')\n * @property {boolean} [depthWrite] (default true)\n * @property {boolean} [depthTest] (default true)\n * @property {number} [size] Points: diameter in world units, or pixels when sizeAttenuation is off (default 1)\n * @property {boolean} [sizeAttenuation] Points: sized in the world, so smaller with distance (default true)\n * @property {ShaderHooks | null} [shader] GLSL of your own, run at fixed points in the shader - waves,\n * dissolves, glows (default none)\n * @property {number} [width] Lines: width in pixels (default 1)\n * @property {number} [dash] Lines: dashed, with dashes this long in the model's units; 0 is solid (default 0)\n * @property {number} [gap] Lines: the gaps between dashes; 0 is as long as the dashes (default 0)\n * @property {number} [dashOffset] Lines: moves the dashes along the lines - animate it for flow (default 0)\n */\n\n// the matcap last: the first map's repeat and offset are every map's, and a matcap has none\nconst MAPS = ['map', 'roughnessMap', 'metalnessMap', 'normalMap', 'bumpMap', 'aoMap', 'emissiveMap', 'lightMap', 'matcap']\n// data maps hold numbers, not colours\nconst LINEAR_MAPS = new Set(['roughnessMap', 'metalnessMap', 'normalMap', 'bumpMap', 'aoMap'])\nconst FLAGS = ['unlit', 'flatShading', 'doubleSided', 'vertexColors', 'depthWrite', 'depthTest', 'sizeAttenuation', 'transparent', 'fog']\nconst NUMBERS = { opacity: [0, 1], roughness: [0, 1], metalness: [0, 1], emissiveIntensity: [0, Infinity], size: [0, Infinity], width: [0, Infinity],\n alphaTest: [0, 1], normalScale: [-Infinity, Infinity], aoMapIntensity: [0, 1], triplanar: [0, Infinity], bumpScale: [-Infinity, Infinity],\n transmission: [0, 1], clearcoat: [0, 1], clearcoatRoughness: [0, 1], sheen: [0, 1], sheenRoughness: [0, 1], ior: [1, Infinity],\n specularIntensity: [0, 1], anisotropy: [0, 1], anisotropyRotation: [-Infinity, Infinity], translucency: [0, 1], toon: [0, 16],\n lightMapIntensity: [0, Infinity], environmentIntensity: [0, Infinity], dash: [0, Infinity], gap: [0, Infinity],\n dashOffset: [-Infinity, Infinity] }\n// colours, and their defaults\nconst COLORS = { color: 0xffffff, emissive: 0x000000, sheenColor: 0xffffff, specularColor: 0xffffff, translucencyColor: 0xffffff }\nconst DEFAULTS = {\n name: '', opacity: 1, alphaTest: 0, roughness: 0.5, metalness: 0, normalScale: 1, bumpScale: 1, aoMapIntensity: 1, triplanar: 0, emissiveIntensity: 1,\n transmission: 0, clearcoat: 0, clearcoatRoughness: 0, sheen: 0, sheenRoughness: 0.5, ior: 1.5, specularIntensity: 1, anisotropy: 0,\n anisotropyRotation: 0, translucency: 0, toon: 0, lightMapIntensity: 1, environmentIntensity: 1, unlit: false, flatShading: false,\n doubleSided: false, vertexColors: false, blending: 'normal', depthWrite: true, depthTest: true, fog: true,\n size: 1, sizeAttenuation: true, width: 1, dash: 0, gap: 0, dashOffset: 0,\n}\nconst OPTIONS = ['name', ...Object.keys(COLORS), ...MAPS, ...FLAGS, ...Object.keys(NUMBERS), 'blending', 'shader']\nconst HOOKS = ['vertex', 'fragment', 'lit', 'uniforms', 'bounds']\n// names the shader keeps for itself\n// the functions hooks can call\nconst HELPERS = ['hash', 'vnoise', 'snoise', 'snoised', 'vfbm', 'sfbm', 'sfbmd', 'voronoi', 'srgb', 'hsv2rgb', 'palette', 'fresnel', 'rotate2', 'rotate3', 'remap', 'saturate']\nconst RESERVED = new RegExp(`^(gl_|phoria)|^(uTime|cameraPosition|${HELPERS.join('|')})$`)\n\n// what agents (and three.js habits) will reach for\nconst HINTS = {\n type: \"phoria2 has one material - drop 'type' and set 'unlit: true' for a flat colour\",\n side: \"use 'doubleSided: true'\",\n wireframe: 'use new Lines({ geometry: edges(geometry) }) for a wireframe',\n shininess: \"use 'roughness' (0 = mirror, 1 = matte)\",\n envMapIntensity: \"use 'environmentIntensity'\",\n reflectivityScale: \"use 'environmentIntensity'\",\n matcapMap: \"use 'matcap'\",\n gradientMap: \"use 'toon' - the number of flat tones\",\n cel: \"use 'toon' - the number of flat tones\",\n celShading: \"use 'toon' - the number of flat tones\",\n specular: \"use 'specularIntensity' and 'specularColor' for a non-metal's reflections, or 'roughness' and 'metalness'\",\n reflectivity: \"use 'ior' (1.5 by default) or 'specularIntensity'\",\n anisotropyStrength: \"use 'anisotropy'\",\n diffuseTransmission: \"use 'translucency'\",\n subsurface: \"use 'translucency' for light through thin surfaces\",\n colour: \"use 'color'\",\n emissiveColor: \"use 'emissive'\",\n alpha: \"use 'opacity'\",\n onBeforeCompile: \"use 'shader': { vertex, fragment, lit, uniforms } - GLSL run inside phoria2's own shader\",\n vertexShader: \"use 'shader': { vertex: 'local.y += sin(local.x + uTime);' } - a hook, not a whole shader\",\n fragmentShader: \"use 'shader': { fragment: 'base.rgb *= 0.5;' } - a hook, not a whole shader\",\n uniforms: \"use 'shader': { uniforms: { uAmount: 1 } }\",\n}\n\n/**\n * The one material: what a surface looks like. Plain objects passed as a `material` become\n * Materials; construct one to share it between nodes. The renderer compiles a shader variant\n * from what is actually used, so an unlit colour costs no lighting maths.\n */\nexport class Material {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n // values from DEFAULTS, in the constructor - one list, which toJSON leaves out\n /** @type {string} */ name\n /** @type {number} */ opacity\n /** Drop pixels with less alpha than this - hard-edged cut-outs, drawn with the opaque pass. @type {number} */ alphaTest\n /** @type {number} */ normalScale\n /** How high a bump map's height of 1 stands, in the mesh's own units. @type {number} */ bumpScale\n /** @type {number} */ aoMapIntensity\n /** Maps projected from the mesh's three axes, this many repeats per unit; 0 uses the UVs. @type {number} */ triplanar\n /** @type {number} */ roughness\n /** @type {number} */ metalness\n /** @type {number} */ emissiveIntensity\n /** How much light passes through, as through glass: 0-1. @type {number} */ transmission\n /** A clear glossy layer over the surface: 0-1. @type {number} */ clearcoat\n /** How glossy the coat is, 0 a mirror. @type {number} */ clearcoatRoughness\n /** The soft bright rim of cloth: 0-1. @type {number} */ sheen\n /** A thin bright rim at 0, a broad soft glow at 1. @type {number} */ sheenRoughness\n /** Index of refraction: how strongly a non-metal reflects (1.5). @type {number} */ ior\n /** Scales a non-metal's reflections, 0-1. @type {number} */ specularIntensity\n /** Brushed metal: 0-1. @type {number} */ anisotropy\n /** Turns the brushing from the UVs' u, in radians. @type {number} */ anisotropyRotation\n /** Light through thin surfaces: 0-1. @type {number} */ translucency\n /** Cartoon shading in this many flat tones; 0 is smooth. @type {number} */ toon\n /** @type {number} */ lightMapIntensity\n /** This material's share of the environment's light and reflections. @type {number} */ environmentIntensity\n /** @type {boolean} */ unlit\n /** @type {boolean} */ flatShading\n /** @type {boolean} */ doubleSided\n /** @type {boolean} */ vertexColors\n /** Fades into the scene's fog with distance. @type {boolean} */ fog\n /** @type {'normal' | 'additive' | 'multiply'} */ blending\n /** @type {boolean} */ depthWrite\n /** @type {boolean} */ depthTest\n /** @type {number} */ size\n /** @type {boolean} */ sizeAttenuation\n /** @type {number} */ width\n /** Lines: dash length in the model's units; 0 is solid. @type {number} */ dash\n /** Lines: gap length; 0 is the dash's. @type {number} */ gap\n /** Lines: how far the dashes have moved along. @type {number} */ dashOffset\n\n /** @type {Record<string, Color>} */\n #colors = Object.fromEntries(Object.entries(COLORS).map(([key, hex]) => [key, new Color(hex)]))\n #transparent = false\n /** @type {Record<string, Texture | null>} */\n #maps = Object.fromEntries(MAPS.map((m) => [m, null]))\n /** @type {Set<() => void>} */\n #onDispose = new Set()\n /** @type {Required<Omit<ShaderHooks, 'bounds'>> & { bounds: number | null } | null} */\n #shader = null\n\n /** @param {MaterialOptions} [options] */\n constructor(options = {}) {\n checkOptions('Material', options, OPTIONS, HINTS)\n Object.assign(this, DEFAULTS)\n for (const [key, value] of /** @type {[string, any][]} */ (Object.entries(options))) {\n if (value === undefined) continue\n if (key in COLORS) this.#colors[key].set(value, 'Material')\n else if (MAPS.includes(key)) this.setMap(key, value)\n else if (FLAGS.includes(key)) this[key] = bool(key, value)\n else if (key in NUMBERS) this[key] = range(key, value, NUMBERS[key])\n else if (key === 'blending') this.blending = checkOneOf('Material', 'blending', value, ['normal', 'additive', 'multiply'])\n else if (key === 'name') this.name = String(value)\n else if (key === 'shader') this.shader = value\n }\n }\n\n /**\n * GLSL hooks run inside the shader, or null. Change its uniforms in place\n * (`material.shader.uniforms.uAmount = 2`); assign a new object to change the code.\n * @returns {Required<Omit<ShaderHooks, 'bounds'>> & { bounds: number | null } | null}\n */\n get shader() { return this.#shader }\n /** @param {ShaderHooks | null} v */\n set shader(v) { this.#shader = shaderHooks(v) }\n\n /** @internal Every texture the material reads: its maps, then its shader's uniform textures. @returns {[string, Texture][]} */\n get allTextures() {\n const maps = this.textures\n const u = this.#shader?.uniforms\n if (!u) return maps\n return [...maps, ...Object.entries(u).filter(([, v]) => v instanceof Texture).map(([k, v]) => /** @type {[string, Texture]} */ ([`shader.${k}`, v]))]\n }\n\n /** @internal\n * A Material from a Material (returned as is) or options.\n * @param {Material | MaterialOptions} input\n * @returns {Material}\n */\n static fromInput(input) {\n if (input instanceof Material) return input\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n fail('Material', `expected material options such as { color: 'orange' }, got ${describe(input)}`)\n }\n return new Material(input)\n }\n\n /** Base colour; assign any colour input. @returns {Color} */\n get color() { return this.#colors.color }\n /** @param {ColorInput} v */\n set color(v) { this.#colors.color.set(v, 'Material') }\n\n /** Glow colour; assign any colour input. @returns {Color} */\n get emissive() { return this.#colors.emissive }\n /** @param {ColorInput} v */\n set emissive(v) { this.#colors.emissive.set(v, 'Material') }\n\n /** The sheen's colour; assign any colour input. @returns {Color} */\n get sheenColor() { return this.#colors.sheenColor }\n /** @param {ColorInput} v */\n set sheenColor(v) { this.#colors.sheenColor.set(v, 'Material') }\n\n /** Tints a non-metal's reflections face on; assign any colour input. @returns {Color} */\n get specularColor() { return this.#colors.specularColor }\n /** @param {ColorInput} v */\n set specularColor(v) { this.#colors.specularColor.set(v, 'Material') }\n\n /** Tints the light that comes through a translucent surface; assign any colour input. @returns {Color} */\n get translucencyColor() { return this.#colors.translucencyColor }\n /** @param {ColorInput} v */\n set translucencyColor(v) { this.#colors.translucencyColor.set(v, 'Material') }\n\n /** @returns {Texture | null} */\n get map() { return this.#maps.map }\n /** @param {MapInput | null} v */\n set map(v) { this.setMap('map', v) }\n /** @returns {Texture | null} */\n get roughnessMap() { return this.#maps.roughnessMap }\n /** @param {MapInput | null} v */\n set roughnessMap(v) { this.setMap('roughnessMap', v) }\n /** @returns {Texture | null} */\n get metalnessMap() { return this.#maps.metalnessMap }\n /** @param {MapInput | null} v */\n set metalnessMap(v) { this.setMap('metalnessMap', v) }\n /** @returns {Texture | null} */\n get normalMap() { return this.#maps.normalMap }\n /** @param {MapInput | null} v */\n set normalMap(v) { this.setMap('normalMap', v) }\n /** @returns {Texture | null} */\n get bumpMap() { return this.#maps.bumpMap }\n /** @param {MapInput | null} v */\n set bumpMap(v) { this.setMap('bumpMap', v) }\n /** @returns {Texture | null} */\n get aoMap() { return this.#maps.aoMap }\n /** @param {MapInput | null} v */\n set aoMap(v) { this.setMap('aoMap', v) }\n /** @returns {Texture | null} */\n get emissiveMap() { return this.#maps.emissiveMap }\n /** @param {MapInput | null} v */\n set emissiveMap(v) { this.setMap('emissiveMap', v) }\n /** Light baked into a texture. @returns {Texture | null} */\n get lightMap() { return this.#maps.lightMap }\n /** @param {MapInput | null} v */\n set lightMap(v) { this.setMap('lightMap', v) }\n /** A picture of a lit sphere that gives the whole look. @returns {Texture | null} */\n get matcap() { return this.#maps.matcap }\n /** @param {MapInput | null} v */\n set matcap(v) { this.setMap('matcap', v) }\n\n /** @internal\n * @param {string} slot one of map, roughnessMap, metalnessMap, normalMap, bumpMap, aoMap, emissiveMap, lightMap, matcap\n * @param {MapInput | null} value\n */\n setMap(slot, value) {\n if (value == null) {\n this.#maps[slot] = null\n return\n }\n if (value instanceof Texture) {\n // a data slot reads its texture as numbers, not colour: one left at the default colour space\n // (loadTexture('n.png'), say) is switched; one set to srgb on purpose is kept, with a word\n if (LINEAR_MAPS.has(slot) && value.colorSpace === 'srgb') {\n if (!value.colorSpaceSet) {\n value.colorSpace = 'linear'\n value.needsUpdate()\n } else warnOnce(value, `'${slot}' holds data, not colour, so its texture should be colorSpace: 'linear' - this one is 'srgb', and will be decoded as colour`)\n }\n this.#maps[slot] = value\n return\n }\n // descriptions and urls take the colour space the slot needs\n const options = typeof value === 'string' ? { url: value } : value\n if (typeof options !== 'object' || Array.isArray(options)) fail('Material', `'${slot}' must be a Texture, a url or texture options, got ${describe(value)}`)\n this.#maps[slot] = new Texture({ colorSpace: LINEAR_MAPS.has(slot) ? 'linear' : 'srgb', ...options })\n }\n\n /** The maps that are set, by slot. @returns {[string, Texture][]} */\n get textures() {\n return /** @type {[string, Texture][]} */ (Object.entries(this.#maps).filter(([, t]) => t))\n }\n\n /** Rendered in the transparent pass: an opacity below 1, additive or multiply blending, or set for maps with soft alpha. @returns {boolean} */\n get transparent() {\n return this.#transparent || this.opacity < 1 || this.transmission > 0 || this.blending !== 'normal'\n }\n /** @param {boolean} v */\n set transparent(v) { this.#transparent = !!v }\n\n /** @internal\n * Which shader features this material needs - renderers compile one program per distinct key.\n * @returns {string}\n */\n get variant() {\n const parts = [this.unlit ? 'unlit' : 'lit']\n for (const [slot] of this.textures) parts.push(slot)\n if (this.alphaTest > 0) parts.push('cutout')\n if (this.transmission > 0) parts.push('glass')\n if (this.clearcoat > 0) parts.push('clearcoat')\n if (this.sheen > 0) parts.push('sheen')\n if (this.anisotropy > 0) parts.push('brushed')\n if (this.translucency > 0) parts.push('translucent')\n if (this.toon > 0) parts.push('toon')\n if (this.flatShading) parts.push('flat')\n if (this.vertexColors) parts.push('vcolor')\n if (this.#shader) parts.push('hooks')\n return parts.join('+')\n }\n\n /** Resolves when every texture has loaded. @returns {Promise<void>} */\n async ready() {\n await Promise.all(this.allTextures.map(([, t]) => t.ready))\n }\n\n /** @returns {Material} */\n clone() {\n const copy = new Material(this.toJSON(true))\n // the colours exactly: a description rounds them to 8-bit sRGB and can't hold values past 1\n for (const [key, c] of Object.entries(this.#colors)) copy.#colors[key].set(c)\n return copy\n }\n\n /** Release GPU resources for this material (programs are shared and kept). */\n dispose() {\n for (const fn of this.#onDispose) fn()\n }\n\n /** @internal For renderers. Returns an unsubscribe function. @param {() => void} fn */\n onDispose(fn) {\n this.#onDispose.add(fn)\n return () => this.#onDispose.delete(fn)\n }\n\n /**\n * Options that differ from the defaults, ready for JSON.\n * @param {boolean} [keepTextures] keep Texture objects instead of their descriptions (for clone)\n * @returns {MaterialOptions}\n */\n toJSON(keepTextures = false) {\n /** @type {Record<string, unknown>} */\n const json = {}\n for (const [key, value] of Object.entries(DEFAULTS)) {\n if (this[key] !== value) json[key] = this[key]\n }\n if (this.#transparent) json.transparent = true\n for (const [key, c] of Object.entries(this.#colors)) if (c.getHex() !== COLORS[key]) json[key] = c.getStyle()\n for (const [slot, t] of this.textures) {\n const desc = keepTextures ? t : t.toJSON()\n if (desc) json[slot] = desc\n }\n const s = this.#shader\n if (s) {\n /** @type {Record<string, unknown>} */\n const hooks = {}\n for (const part of ['vertex', 'fragment', 'lit']) if (s[part]) hooks[part] = s[part]\n const uniforms = Object.entries(s.uniforms).map(([k, v]) => [k, v instanceof Texture ? (keepTextures ? v : v.toJSON())\n : v instanceof Color ? v.getStyle() : Array.isArray(v) || ArrayBuffer.isView(v) ? Array.from(/** @type {ArrayLike<number>} */ (v)) : v])\n if (uniforms.length) hooks.uniforms = Object.fromEntries(uniforms.filter(([, v]) => v != null))\n if (s.bounds !== null) hooks.bounds = s.bounds\n json.shader = hooks\n }\n return json\n }\n}\n\n/** @param {string} name @param {unknown} v */\nfunction bool(name, v) {\n if (typeof v !== 'boolean') fail('Material', `'${name}' must be true or false, got ${describe(v)}`)\n return v\n}\n\n/** @param {string} name @param {unknown} v @param {number[]} limits */\nfunction range(name, v, [min, max]) {\n checkNumber('Material', name, v)\n const n = /** @type {number} */ (v)\n if (n < min || n > max) fail('Material', `'${name}' must be ${max === Infinity ? `${min} or more` : `${min}-${max}`}, got ${n}`)\n return n\n}\n\n/**\n * Shader hooks checked and copied: each piece of code a string, the uniforms by valid names, their\n * values numbers, two to four numbers, colours or textures.\n * @param {ShaderHooks | null | undefined} v\n */\nfunction shaderHooks(v) {\n if (v == null) return null\n if (typeof v !== 'object' || Array.isArray(v)) fail('Material', `'shader' is { vertex, fragment, lit, uniforms, bounds } - GLSL hooks - got ${describe(v)}`)\n checkOptions('Material shader', v, HOOKS, {\n vertexShader: \"use 'vertex' - a few lines run on each vertex, not a whole shader\",\n fragmentShader: \"use 'fragment' (before lighting) or 'lit' (after) - a few lines, not a whole shader\",\n })\n for (const part of ['vertex', 'fragment', 'lit']) {\n if (v[part] !== undefined && typeof v[part] !== 'string') fail('Material', `shader '${part}' is GLSL as a string, got ${describe(v[part])}`)\n }\n if (!v.vertex && !v.fragment && !v.lit) fail('Material', \"'shader' needs at least one of 'vertex', 'fragment' or 'lit'\")\n const uniforms = v.uniforms ?? {}\n if (typeof uniforms !== 'object' || Array.isArray(uniforms)) fail('Material', `shader 'uniforms' is an object of name: value, got ${describe(uniforms)}`)\n /** @type {Record<string, ShaderUniform>} */\n const own = {}\n for (const [name, value] of Object.entries(uniforms)) {\n if (!/^[A-Za-z_]\\w*$/.test(name)) fail('Material', `shader uniform '${name}' isn't a GLSL name - letters, digits and _, not starting with a digit`)\n if (RESERVED.test(name)) fail('Material', `shader uniform '${name}' is a name phoria2 keeps${name === 'uTime' ? \" - uTime is there already, the View's clock in seconds\" : name === 'cameraPosition' ? \" - cameraPosition is there already, the camera's world position\" : HELPERS.includes(name) ? ` - ${name}() is a function every hook can call` : ''}`)\n own[name] = uniformValue(name, value)\n }\n const bounds = v.bounds === undefined || v.bounds === null ? null : Math.max(0, checkNumber('Material', 'shader bounds', v.bounds))\n return { vertex: v.vertex ?? '', fragment: v.fragment ?? '', lit: v.lit ?? '', uniforms: own, bounds }\n}\n\n/** A uniform's value as kept: numbers and arrays as given, colours as Colors, textures as Textures. @param {string} name @param {unknown} v @returns {ShaderUniform} */\nfunction uniformValue(name, v) {\n if (typeof v === 'number' && Number.isFinite(v)) return v\n if ((Array.isArray(v) || ArrayBuffer.isView(v)) && /** @type {ArrayLike<unknown>} */ (v).length >= 2 && /** @type {ArrayLike<unknown>} */ (v).length <= 4 && Array.from(/** @type {ArrayLike<unknown>} */ (v)).every((n) => typeof n === 'number' && Number.isFinite(n))) {\n return Array.from(/** @type {ArrayLike<number>} */ (v))\n }\n if (v instanceof Texture) return v\n if (v instanceof Color) return v\n if (v && typeof v === 'object' && 'url' in v) return new Texture(/** @type {any} */ (v))\n if (typeof v === 'string') return Color.fromInput(v, 'Material')\n return fail('Material', `shader uniform '${name}' is a number, two to four numbers, a colour or a Texture, got ${describe(v)}`)\n}\n","// Turns the option objects drawables accept into Geometry and Material. Only objects that need no\n// extra code: generator descriptions such as { type: 'box' } go through create(), so an app that\n// never uses descriptions doesn't carry every generator.\nimport { Geometry } from './geometry/Geometry.js'\nimport { Material } from './material/Material.js'\nimport { describe, fail } from './validate.js'\n\n/** @import { MaterialOptions } from './material/Material.js' */\n/** @import { GeometryOptions } from './geometry/Geometry.js' */\n\n/**\n * @param {Geometry | GeometryOptions} input a Geometry, or its options ({ positions, indices, ... })\n * @param {string} owner\n * @returns {Geometry}\n */\nexport function resolveGeometry(input, owner) {\n if (input instanceof Geometry) return input\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n fail(owner, `'geometry' must be a Geometry such as box(2), got ${describe(input)}`)\n }\n if ('type' in input) {\n const type = /** @type {{ type: unknown }} */ (input).type\n fail(owner, `'geometry' { type: '${type}' } is a description - use the generator directly, e.g. ` +\n `${type}(...), or build the whole node with create({ type: '${owner.toLowerCase()}', geometry: { type: '${type}' } })`)\n }\n return new Geometry(/** @type {GeometryOptions} */ (input))\n}\n\n/**\n * @param {Material | MaterialOptions | undefined} input\n * @returns {Material}\n */\nexport function resolveMaterial(input) {\n return input === undefined ? new Material() : Material.fromInput(input)\n}\n","// 3x3 matrices as column-major Float32Array(9). Signatures follow gl-matrix.\n\n/** @returns {Float32Array} identity */\nexport function create() {\n return identity(new Float32Array(9))\n}\n\n/** @template {Float32Array | number[]} T @param {T} out @returns {T} */\nexport function identity(out) {\n out.fill(0)\n out[0] = out[4] = out[8] = 1\n return out\n}\n\n// Inverse transpose of a 4x4 matrix's upper 3x3 - transforms normals correctly under\n// non-uniform scale. Returns null if the matrix can't be inverted.\n/** @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a 4x4 @returns {T | null} */\nexport function normalFromMat4(out, a) {\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]\n\n const b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10\n const b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11\n const b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12\n const b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30\n const b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31\n const b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32\n\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06\n if (!det) return null\n det = 1 / det\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det\n out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det\n out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det\n out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det\n out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det\n out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det\n out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det\n out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det\n out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det\n return out\n}\n\n/** The upper-left 3x3 of a 4x4. @template {Float32Array | number[]} T @param {T} out @param {Float32Array | number[]} a @returns {T} */\nexport function fromMat4(out, a) {\n out[0] = a[0]; out[1] = a[1]; out[2] = a[2]\n out[3] = a[4]; out[4] = a[5]; out[5] = a[6]\n out[6] = a[8]; out[7] = a[9]; out[8] = a[10]\n return out\n}\n","import * as mat3 from '../math/mat3.js'\nimport * as mat4 from '../math/mat4.js'\nimport * as quat from '../math/quat.js'\nimport { Box3 } from '../value/Box3.js'\nimport { Color } from '../value/Color.js'\nimport { Euler } from '../value/Euler.js'\nimport { Mat4 } from '../value/Mat4.js'\nimport { Quat } from '../value/Quat.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { checkOptions, describe, fail } from '../validate.js'\nimport { Clip } from '../clip.js'\n\n/** @import { ColorInput, QuatInput, Vec3Input } from '../types.js' */\n/** @import { Hit } from '../Raycaster.js' */\n/** @import { Camera } from './cameras.js' */\n/** @import { ClipOptions } from '../clip.js' */\n/** @import { Ray } from '../value/Ray.js' */\n\n/**\n * A drag in progress, given to onDrag handlers: 'start' once the pointer has moved off where it\n * was pressed, 'move' as it moves, 'end' when it lets go.\n * @typedef {object} Drag\n * @property {'start' | 'move' | 'end'} phase\n * @property {Hit} hit what was pressed\n * @property {Node} node the node whose handler this is (the hit's, or the nearest above it with one)\n * @property {Ray} ray the pointer's ray now, in world space\n * @property {{ normal: Vec3, point: Vec3 }} plane what it is dragged across - horizontal through the\n * pressed point unless the handler sets another at 'start'\n * @property {Vec3} start where the drag began on the plane\n * @property {Vec3 | null} point where the pointer is on the plane now (null if it has left the plane, as at the horizon)\n * @property {Vec3} delta point - start (the last good point's, when it has left the plane)\n * @property {PointerEvent} event\n */\n\n/** @typedef {{ color: Color, width: number }} Outline */\n\n/**\n * Per-frame behaviour: `(node, dt, t) => void`, with dt and t in seconds.\n * @typedef {(node: any, dt: number, t: number) => void} UpdateHandler\n */\n\n/**\n * @typedef {object} NodeOptions\n * @property {string} [name]\n * @property {Vec3Input} [position]\n * @property {Vec3Input | Euler} [rotation] Euler angles in radians, XYZ order\n * @property {QuatInput} [quaternion] [x, y, z, w] or { x, y, z, w } - instead of rotation\n * @property {Vec3Input | number} [scale] a number scales uniformly\n * @property {boolean} [visible]\n * @property {boolean} [pickable] include in view.pick() (default true)\n * @property {boolean} [matrixAutoUpdate] recompose the local matrix each frame (default true)\n * @property {Node[]} [children]\n * @property {Record<string, unknown>} [userData] anything of your own\n * @property {UpdateHandler | UpdateHandler[]} [onUpdate]\n * @property {((hit: Hit) => any) | null} [tooltip] tooltip for anything picked in this subtree; nearer nodes win, and\n * all win over the View's\n * @property {ColorInput | null | false} [highlight] hover tint for this subtree, over the View's; false for none - a\n * floor or wall left plain under a View that tints everything else (null: the View's)\n * @property {boolean} [highlightWhole] hovering any part of this subtree tints all of it, as one thing - a\n * piece of furniture, a machine - rather than just the part under the pointer (default false)\n * @property {((hit: Hit | null) => void) | null} [onHover] called as the thing under the pointer in this subtree changes\n * (null when it leaves the subtree)\n * @property {((hit: Hit) => void) | null} [onClick] called when something in this subtree is clicked\n * @property {((camera: Camera) => boolean) | null} [showFrom] draw this subtree only for cameras this returns true for\n * @property {((drag: Drag) => void) | null} [onDrag] drag this subtree with the pointer: called as a drag starts, moves and ends\n * (the camera stays still meanwhile); a press without a drag still clicks\n * @property {ColorInput | { color?: ColorInput, width?: number } | null} [outline] draw a line round this subtree's silhouette, on top of\n * everything - for selection. A colour, or { color, width } with width in pixels (default 2)\n * @property {ClipOptions | Clip | null} [clip] cut away everything in this subtree on one side of a plane in this\n * node's space - for cutaways. The nearest clip above a mesh is the one that cuts it\n */\n\nexport const NODE_OPTIONS = ['name', 'position', 'rotation', 'quaternion', 'scale', 'visible', 'pickable',\n 'matrixAutoUpdate', 'children', 'userData', 'onUpdate', 'tooltip', 'highlight', 'highlightWhole', 'onHover', 'onClick', 'showFrom', 'clip', 'onDrag', 'outline']\n\n// three.js habits that would otherwise fail with a plain \"unknown option\"\nexport const NODE_HINTS = {\n rotationX: \"use rotation: [x, y, z] (radians)\",\n scaleX: 'use scale: [x, y, z] or a single number',\n translate: \"use position: [x, y, z]\",\n parent: 'add the node to its parent instead: parent.add(node)',\n type: \"'type' is only used in descriptions passed to create() or add()\",\n clippingPlanes: 'use clip: { normal, offset, cap } - one plane, cutting this node and everything under it',\n draggable: 'give the node an onDrag handler: onDrag: (drag) => { ... }',\n onDragStart: \"use onDrag - drag.phase is 'start', 'move' or 'end'\",\n onDragEnd: \"use onDrag - drag.phase is 'start', 'move' or 'end'\",\n selected: \"outline what's selected: node.outline = '#ffcc00'\",\n}\n\n/** @type {Function[]} */\nconst NO_HANDLERS = []\nconst UP = new Float32Array([0, 1, 0])\nconst tmpMat = new Float32Array(16)\nconst tmpMat3 = new Float32Array(9)\n\n/** The base of everything in a scene: a transform (position, rotation, scale) and children. */\nexport class Node {\n /** The description type, used by create() and toJSON(). */\n static type = 'node'\n /**\n * The options it takes, and hints for names people reach for instead. A subclass with options of\n * its own adds to its parent's: static get OPTIONS() { return [...super.OPTIONS, 'blink'] }\n * @type {string[]}\n */\n static OPTIONS = NODE_OPTIONS\n /** @type {Record<string, string>} */\n static HINTS = NODE_HINTS\n\n name = ''\n #position = new Vec3()\n #scale = new Vec3(1, 1, 1)\n #quaternion = new Quat()\n #rotation = new Euler()\n visible = true\n /** Include in picking. */\n pickable = true\n /** Recompose the local matrix from position/rotation/scale each frame. */\n matrixAutoUpdate = true\n /** Local transform. @type {Mat4} */ matrix = new Mat4()\n /** Read only: parent's world matrix x local matrix, as of the last update. @type {Mat4} */\n worldMatrix = new Mat4()\n /** Anything of your own; copied by clone() and kept in toJSON() when it is plain data. */\n userData = {}\n /** Tooltip for anything picked in this subtree (nearest wins, over the View's). @type {((hit: Hit) => any) | null} */\n tooltip = null\n /** Called as the thing under the pointer in this subtree changes; null when it leaves. @type {((hit: Hit | null) => void) | null} */\n onHover = null\n /** Called when something in this subtree is clicked. @type {((hit: Hit) => void) | null} */\n onClick = null\n /** Draw this subtree only for cameras this returns true for - per frame, without changing the scene. @type {((camera: Camera) => boolean) | null} */\n showFrom = null\n /** @internal An HTML element shown over the canvas while this node is drawn (a chart's legend). @type {HTMLElement | null} */\n overlay = null\n /** @type {Clip | null} */\n #clip = null\n /** Called as the pointer drags this subtree: see Drag. @type {((drag: Drag) => void) | null} */\n onDrag = null\n /** @type {Outline | null} */\n #outline = null\n /** @type {Color | null | false} */\n #highlight = null\n /** Hovering any part of this subtree tints all of it, not just the part under the pointer. */\n highlightWhole = false\n /** Hover and click listeners besides onHover and onClick, made on the first on(). @type {{ hover: Set<Function>, click: Set<Function> } | null} */\n #listeners = null\n\n /** @type {Node | null} */\n #parent = null\n /** @type {Node[]} */\n #children = []\n /** @type {UpdateHandler[]} */\n #handlers = []\n\n /** Where it is, in its parent's space. Assigning copies the value in: node.position = [1, 2, 3]. @returns {Vec3} */\n get position() { return this.#position }\n /** @param {Vec3Input} v */\n set position(v) { this.#position.copy(v, this.constructor.name) }\n /** Its size along each axis; assigning copies, and a number scales all three. @returns {Vec3} */\n get scale() { return this.#scale }\n /** @param {Vec3Input | number} v */\n set scale(v) { this.#scale.copy(/** @type {any} */ (v), this.constructor.name) }\n /** Euler angles in radians, XYZ order; kept in sync with quaternion. Assigning copies. @returns {Euler} */\n get rotation() { return this.#rotation }\n /** @param {Vec3Input} v */\n set rotation(v) { this.#rotation.copy(/** @type {any} */ (v), this.constructor.name) }\n /** Kept in sync with rotation. Assigning copies, normalised. @returns {Quat} */\n get quaternion() { return this.#quaternion }\n /** @param {QuatInput} v */\n set quaternion(v) { this.#quaternion.copy(v, this.constructor.name).normalize() }\n\n /** @param {NodeOptions} [options] */\n constructor(options = {}) {\n const Class = /** @type {typeof Node & { OPTIONS?: string[], HINTS?: Record<string, string> }} */ (new.target)\n checkOptions(Class.name, options, Class.OPTIONS, { ...NODE_HINTS, ...Class.HINTS })\n this.rotation.onChange = () => quat.fromEulerXYZ(this.quaternion, this.rotation.x, this.rotation.y, this.rotation.z)\n this.quaternion.onChange = () => this.rotation.setFromQuat(this.quaternion)\n\n const owner = Class.name\n if (options.name !== undefined) this.name = String(options.name)\n if (options.position !== undefined) this.position.copy(options.position, owner)\n if (options.rotation !== undefined) this.rotation.copy(/** @type {any} */ (options.rotation), owner)\n if (options.quaternion !== undefined) this.quaternion.copy(options.quaternion, owner).normalize()\n if (options.scale !== undefined) this.scale.copy(options.scale, owner)\n if (options.visible !== undefined) this.visible = !!options.visible\n if (options.pickable !== undefined) this.pickable = !!options.pickable\n if (options.matrixAutoUpdate !== undefined) this.matrixAutoUpdate = !!options.matrixAutoUpdate\n if (options.userData !== undefined) this.userData = options.userData\n if (options.onUpdate) [options.onUpdate].flat().forEach((fn) => this.onUpdate(fn))\n for (const key of ['tooltip', 'onHover', 'onClick', 'showFrom', 'onDrag']) {\n const fn = options[key]\n if (fn === undefined || fn === null) continue\n if (typeof fn !== 'function') fail(owner, `'${key}' must be a function, got ${describe(fn)}`)\n this[key] = fn\n }\n if (options.highlight != null) this.#setHighlight(options.highlight, owner)\n if (options.highlightWhole !== undefined) {\n if (typeof options.highlightWhole !== 'boolean') fail(owner, `'highlightWhole' must be true or false, got ${describe(options.highlightWhole)}`)\n this.highlightWhole = options.highlightWhole\n }\n if (options.clip != null) this.#clip = Clip.fromInput(options.clip, owner)\n if (options.outline != null) this.#setOutline(options.outline)\n if (options.children) for (const child of options.children) this.add(child)\n }\n\n /**\n * Hover tint for this subtree, over the View's: a colour, false for none, or null to use the View's.\n * @returns {Color | null | false}\n */\n get highlight() {\n return this.#highlight\n }\n\n /** @param {ColorInput | null | false} value */\n set highlight(value) {\n this.#setHighlight(value, this.constructor.name)\n }\n\n /** @param {ColorInput | null | false | true} value @param {string} owner */\n #setHighlight(value, owner) {\n if (value === true) fail(owner, \"'highlight' is a colour, false for no tint, or null to use the View's - got true\")\n this.#highlight = value == null ? null : value === false ? false : Color.fromInput(value, owner)\n }\n\n /**\n * The section plane cutting this subtree, or null. Set { normal, offset, cap }, a Clip or null;\n * move the cut by changing its offset or normal in place.\n * @returns {Clip | null}\n */\n get clip() {\n return this.#clip\n }\n\n /** @param {ClipOptions | Clip | null} value */\n set clip(value) {\n this.#clip = value == null ? null : Clip.fromInput(value, this.constructor.name)\n }\n\n /**\n * A line round this subtree's silhouette, drawn over everything - for showing what is selected -\n * or null. Set a colour, { color, width } (pixels, default 2) or null.\n * @returns {Outline | null}\n */\n get outline() {\n return this.#outline\n }\n\n /** @param {ColorInput | { color?: ColorInput, width?: number } | null} value */\n set outline(value) {\n this.#setOutline(value)\n }\n\n /** @param {ColorInput | { color?: ColorInput, width?: number } | null} value */\n #setOutline(value) {\n const owner = this.constructor.name\n if (value == null) {\n this.#outline = null\n return\n }\n const options = typeof value === 'object' && !Array.isArray(value) && !ArrayBuffer.isView(value) && !(value instanceof Color)\n ? /** @type {{ color?: ColorInput, width?: number }} */ (value) : { color: /** @type {ColorInput} */ (value) }\n checkOptions(owner, options, ['color', 'width'], {}, 'outline')\n const width = options.width ?? 2\n if (typeof width !== 'number' || !(width > 0) || width > 8) fail(owner, `'outline.width' is in pixels, above 0 and up to 8, got ${describe(width)}`)\n this.#outline = { color: Color.fromInput(options.color ?? '#ffcc00', owner), width }\n }\n\n /** @returns {Node | null} */\n get parent() {\n return this.#parent\n }\n\n /** Read only - use add() and remove(). @returns {readonly Node[]} */\n get children() {\n return this.#children\n }\n\n /** The topmost ancestor (the scene, once added to one). @returns {Node} */\n get root() {\n /** @type {Node} */\n let n = this\n while (n.#parent) n = n.#parent\n return n\n }\n\n /**\n * Add children. Returns the first one, so `const cube = scene.add(new Mesh({...}))` keeps a\n * reference. A list works too: `group.add(...parts)`. For a description, add(create({ type: 'mesh', ... })).\n * @template {Node} T\n * @param {T} [first] (optional only in its type, so a spread list type-checks - add() needs one)\n * @param {...Node} more\n * @returns {T}\n */\n add(first, ...more) {\n if (first === undefined) fail(this.constructor.name, 'add() needs a node to add - add(new Mesh({...})), or add(...nodes) for several')\n const nodes = [first, ...more].map((n) => toNode(n))\n for (const node of nodes) {\n if (node === this) fail(this.constructor.name, \"can't add a node to itself\")\n for (let p = this.#parent; p; p = p.#parent) {\n if (p === node) fail(this.constructor.name, \"can't add an ancestor as a child - that would make a loop\")\n }\n if (node.#parent) node.#parent.#detach(node)\n node.#parent = this\n this.#children.push(node)\n }\n return /** @type {T} */ (nodes[0])\n }\n\n /** Remove children. Safe inside update handlers and traverse(): the walk goes on over the children as they were. @param {...Node} nodes @returns {this} */\n remove(...nodes) {\n for (const node of nodes) {\n if (node.#parent === this) this.#detach(node)\n }\n return this\n }\n\n /** @returns {this} */\n removeFromParent() {\n this.#parent?.remove(this)\n return this\n }\n\n /** @param {Node} node */\n #detach(node) {\n this.#children.splice(this.#children.indexOf(node), 1)\n node.#parent = null\n }\n\n /**\n * Visit this node and every descendant, depth first. The children are copied before they are\n * visited, so fn can remove or move nodes without the walk skipping one.\n * @param {(node: Node) => void} fn\n */\n traverse(fn) {\n fn(this)\n if (this.#children.length) for (const child of [...this.#children]) child.traverse(fn)\n }\n\n /** The first descendant (or this) with a name. @param {string} name @returns {Node | undefined} */\n find(name) {\n if (this.name === name) return this\n for (const child of this.#children) {\n const found = child.find(name)\n if (found) return found\n }\n return undefined\n }\n\n /** Every descendant (and this) matching a predicate. @param {(node: Node) => boolean} predicate @returns {Node[]} */\n findAll(predicate) {\n /** @type {Node[]} */\n const found = []\n this.traverse((n) => predicate(n) && found.push(n))\n return found\n }\n\n /**\n * Per-frame behaviour: node.onUpdate((node, dt, t) => {}) adds a handler and returns a function\n * that removes it. A node can have several, so it's called, not assigned like onClick.\n * @returns {(fn: UpdateHandler) => () => void}\n */\n get onUpdate() { return (fn) => this.#addUpdate(fn) }\n /** @param {unknown} _fn */\n set onUpdate(_fn) {\n fail(this.constructor.name, \"call onUpdate rather than assigning it - node.onUpdate((node, dt, t) => {}) adds a handler (a node can have several)\")\n }\n\n /** @param {UpdateHandler} fn @returns {() => void} */\n #addUpdate(fn) {\n if (typeof fn !== 'function') fail(this.constructor.name, `onUpdate expects a function (node, dt, t) => {}, got ${describe(fn)}`)\n this.#handlers.push(fn)\n return () => {\n const i = this.#handlers.indexOf(fn)\n if (i !== -1) this.#handlers.splice(i, 1)\n }\n }\n\n /**\n * Listen for the pointer on this subtree as well as its own onHover and onClick - for add-ons, and\n * anything that mustn't replace the app's handler. Returns a function that stops listening. (A drag\n * has one handler, onDrag: one thing moves a node at a time.)\n * @param {'hover' | 'click'} event\n * @param {(hit: Hit | null) => void} fn hover hears null when the pointer leaves\n * @returns {() => void}\n */\n on(event, fn) {\n const owner = this.constructor.name\n if (event !== 'hover' && event !== 'click') fail(owner, `on() listens for 'hover' or 'click', got ${describe(event)}${event === 'drag' ? \" - a drag has one handler: onDrag\" : ''}`)\n if (typeof fn !== 'function') fail(owner, `on('${event}', fn) needs a function, got ${describe(fn)}`)\n this.#listeners ??= { hover: new Set(), click: new Set() }\n const set = this.#listeners[event]\n set.add(fn)\n return () => { set.delete(fn) }\n }\n\n /** @internal Everything to tell of the pointer on this node: its own handler, then its listeners. @param {'hover' | 'click'} event @returns {Function[]} */\n handlersFor(event) {\n const own = event === 'hover' ? this.onHover : this.onClick\n const more = this.#listeners?.[event]\n if (!more?.size) return own ? [own] : NO_HANDLERS\n return own ? [own, ...more] : [...more]\n }\n\n /** @internal Run this node's update handlers. @param {number} dt @param {number} t */\n runHandlers(dt, t) {\n for (const fn of this.#handlers) fn(this, dt, t)\n }\n\n /** @internal @returns {boolean} */\n get hasHandlers() {\n return this.#handlers.length > 0\n }\n\n // ---- transforms: all chainable, and all in the node's local frame ----\n\n /** @param {number} x @param {number} y @param {number} z @returns {this} */\n translate(x, y, z) {\n const offset = new Vec3(x, y, z).applyQuaternion(this.quaternion)\n this.position.add(offset)\n return this\n }\n\n /** @param {number} d @returns {this} */\n translateX(d) { return this.translate(d, 0, 0) }\n /** @param {number} d @returns {this} */\n translateY(d) { return this.translate(0, d, 0) }\n /** @param {number} d @returns {this} */\n translateZ(d) { return this.translate(0, 0, d) }\n\n /** Rotate about a local axis. @param {Vec3Input} axis @param {number} rad @returns {this} */\n rotate(axis, rad) {\n const a = Vec3.fromInput(axis, this.constructor.name).normalize()\n this.quaternion.multiply(new Quat().setFromAxisAngle(a, rad))\n return this\n }\n\n /** @param {number} rad @returns {this} */\n rotateX(rad) { return this.rotate([1, 0, 0], rad) }\n /** @param {number} rad @returns {this} */\n rotateY(rad) { return this.rotate([0, 1, 0], rad) }\n /** @param {number} rad @returns {this} */\n rotateZ(rad) { return this.rotate([0, 0, 1], rad) }\n\n /**\n * Turn so the node's -Z axis points at a world position or node (cameras and lights look down -Z),\n * with its +Y leaning toward up - a world direction, +Y unless given. The roll is undefined when\n * looking straight along up, so for something that turns through every heading in a plane - a\n * craft seen face on, moving in x-y - give an up out of that plane: [0, 0, 1].\n * @param {Vec3Input | Node} target\n * @param {Vec3Input} [up]\n * @returns {this}\n */\n lookAt(target, up) {\n const at = target instanceof Node ? target.updateWorld().worldPosition : Vec3.fromInput(target, this.constructor.name)\n const toward = up === undefined ? UP : Vec3.fromInput(up, `${this.constructor.name}.lookAt() up`).normalize()\n this.updateWorld()\n const eye = this.worldPosition\n if (eye.equals(at, 1e-9)) return this\n // looking straight along up needs a different one\n const dir = at.clone().sub(eye).normalize()\n const along = Math.abs(dir.dot(toward)) > 0.9999\n const lean = along ? (Math.abs(toward[1]) > 0.9 ? [0, 0, -1] : UP) : toward\n mat4.targetTo(tmpMat, eye, at, lean)\n const world = quat.fromMat3(new Float32Array(4), mat3.fromMat4(tmpMat3, tmpMat))\n // into the parent's frame\n if (this.#parent) {\n const parentRot = quat.normalize(new Float32Array(4), quat.fromMat3(new Float32Array(4), normalizedRotation(this.#parent.worldMatrix)))\n quat.multiply(world, quat.invert(parentRot, parentRot), world)\n }\n this.quaternion.copy(quat.normalize(world, world))\n return this\n }\n\n /** Recompose `matrix` from position, rotation and scale. @returns {this} */\n updateMatrix() {\n this.matrix.compose(this.position, this.quaternion, this.scale)\n return this\n }\n\n /**\n * Bring world matrices up to date: this node's ancestors, then this node and its descendants.\n * Scenes do this every frame; call it to read world values in between.\n * @returns {this}\n */\n updateWorld() {\n if (this.#parent) this.#parent.#updateAncestors()\n this.updateWorldTree()\n return this\n }\n\n #updateAncestors() {\n if (this.#parent) this.#parent.#updateAncestors()\n this.#updateSelf()\n }\n\n #updateSelf() {\n if (this.matrixAutoUpdate) this.updateMatrix()\n if (this.#parent) mat4.multiply(this.worldMatrix, this.#parent.worldMatrix, this.matrix)\n else this.worldMatrix.copy(this.matrix)\n }\n\n /**\n * Bring the world matrices of this node and everything under it up to date now, from the parent's\n * current world matrix - before reading worldPosition or bounds after moving things, without\n * waiting for the next frame.\n */\n updateWorldTree() {\n this.#updateSelf()\n for (const child of this.#children) child.updateWorldTree()\n }\n\n /** World position as of the last update. @returns {Vec3} */\n get worldPosition() {\n return this.worldMatrix.getPosition()\n }\n\n /** World rotation as of the last update. @returns {Quat} */\n get worldQuaternion() {\n const q = quat.fromMat3(new Float32Array(4), normalizedRotation(this.worldMatrix))\n return new Quat(q[0], q[1], q[2], q[3]).normalize()\n }\n\n /** World scale as of the last update. @returns {Vec3} */\n get worldScale() {\n return this.worldMatrix.getScale()\n }\n\n /** World space bounds of this node and its descendants, brought up to date first. @returns {Box3} */\n get bounds() {\n this.updateWorld()\n const box = new Box3()\n this.traverse((n) => n.expandBounds(box))\n return box\n }\n\n /**\n * The world-space box of what a camera draws of this subtree: like bounds, but leaving out hidden\n * nodes and those whose showFrom turns them away from that camera - a chart's axis labels for\n * the edges it isn't showing, say. Framing fits this, so the picture fills the view.\n * @param {Camera} camera\n * @returns {Box3}\n */\n boundsFrom(camera) {\n this.updateWorld()\n const box = new Box3()\n this.eachShownTo(camera, (n) => n.expandBounds(box))\n return box\n }\n\n /** @internal\n * Does this camera draw this node (leaving its ancestors aside)? Visible, and not turned away by\n * showFrom. The one rule drawing, picking, framing and redraw-watching all use.\n * @param {Camera} camera\n * @returns {boolean}\n */\n shownTo(camera) {\n return this.visible && (!this.showFrom || this.showFrom(camera))\n }\n\n /** @internal Visit this node and every descendant the camera draws - a hidden node's subtree is skipped. @param {Camera} camera @param {(node: Node) => void} fn */\n eachShownTo(camera, fn) {\n if (!this.shownTo(camera)) return\n fn(this)\n for (const child of this.#children) child.eachShownTo(camera, fn)\n }\n\n /** @internal Grow a world space box by this node's own geometry (none for a plain node). @param {Box3} box */\n expandBounds(box) {\n return box\n }\n\n /**\n * A copy of this node; with `deep` (the default) its children are cloned too. Geometry and\n * materials are shared, not copied.\n * @param {{ deep?: boolean }} [options]\n * @returns {this}\n */\n clone({ deep = true } = {}) {\n const Class = /** @type {any} */ (this.constructor)\n const copy = new Class(this.cloneOptions())\n copy.userData = structuredClone(this.userData)\n copy.matrixAutoUpdate = this.matrixAutoUpdate\n if (!copy.matrixAutoUpdate) copy.matrix.copy(this.matrix)\n for (const fn of this.#handlers) copy.onUpdate(fn)\n if (deep) for (const child of this.#children) copy.add(child.clone())\n return copy\n }\n\n /** @internal Constructor options that recreate this node (without children). @returns {Record<string, unknown>} */\n cloneOptions() {\n return {\n name: this.name,\n position: this.position.toArray(),\n quaternion: this.quaternion.toArray(),\n scale: this.scale.toArray(),\n visible: this.visible,\n pickable: this.pickable,\n tooltip: this.tooltip,\n highlight: this.highlight,\n highlightWhole: this.highlightWhole,\n onHover: this.onHover,\n onClick: this.onClick,\n showFrom: this.showFrom,\n clip: this.#clip ? this.#clip.toJSON() : null,\n onDrag: this.onDrag,\n outline: this.#outline ? { color: this.#outline.color.getStyle(), width: this.#outline.width } : null,\n }\n }\n\n /**\n * This node and its descendants as a plain description that create() rebuilds. Handlers are\n * behaviour, not data, and are left out.\n * @returns {Record<string, unknown>}\n */\n toJSON() {\n /** @type {Record<string, unknown>} */\n const json = { type: /** @type {typeof Node} */ (this.constructor).type }\n if (this.name) json.name = this.name\n if (!this.position.equals([0, 0, 0])) json.position = this.position.toArray()\n if (this.rotation.x || this.rotation.y || this.rotation.z) json.rotation = this.rotation.toArray()\n if (!this.scale.equals([1, 1, 1])) json.scale = this.scale.toArray()\n if (!this.visible) json.visible = false\n if (!this.pickable) json.pickable = false\n if (!this.matrixAutoUpdate) json.matrixAutoUpdate = false\n if (this.highlight) json.highlight = this.highlight.getStyle()\n else if (this.highlight === false) json.highlight = false\n if (this.highlightWhole) json.highlightWhole = true\n if (this.#clip) json.clip = this.#clip.toJSON()\n if (this.#outline) json.outline = { color: this.#outline.color.getStyle(), width: this.#outline.width }\n if (Object.keys(this.userData).length) json.userData = this.userData\n Object.assign(json, this.jsonOptions())\n if (this.#children.length) json.children = this.#children.map((c) => c.toJSON())\n return json\n }\n\n /** @internal Subclass-specific description fields. @returns {Record<string, unknown>} */\n jsonOptions() {\n return {}\n }\n\n /** Release GPU resources used by this subtree (shared resources are released by the renderer only when unused). */\n dispose() {\n this.traverse((n) => n !== this && n.dispose())\n }\n}\n\n/**\n * A point property's new value: copied into the vector it has, so references to it stay good, or\n * null to clear it. @internal\n * @param {Vec3 | null} current @param {import('../types.js').Vec3Input | null | undefined} v @param {string} owner\n * @returns {Vec3 | null}\n */\nexport function setPoint(current, v, owner) {\n if (v === null || v === undefined) return null\n return current ? current.copy(v, owner) : Vec3.fromInput(v, owner)\n}\n\n/**\n * @internal Where a world position or node is in a node's parent's space - the space its position,\n * and a camera's or light's target, are in.\n * @param {Node} node @param {Vec3Input | Node} target\n * @returns {Vec3}\n */\nexport function inParentSpace(node, target) {\n const at = target instanceof Node ? target.updateWorld().worldPosition : Vec3.fromInput(target, `${node.constructor.name}.lookAt()`)\n const parent = node.parent\n return parent ? at.applyMatrix4(parent.updateWorld().worldMatrix.clone().invert()) : at\n}\n\n/** @param {unknown} n @returns {Node} */\nfunction toNode(n) {\n if (n instanceof Node) return n\n if (n && typeof n === 'object' && 'type' in n) {\n return fail('Node', `add() takes nodes - build one from a description with add(create({ type: '${n.type}', ... }))`)\n }\n return fail('Node', `add() expects nodes, got ${describe(n)}`)\n}\n\n// The rotation part of a matrix with any scale divided out, as a 3x3.\n/** @param {Float32Array} m @returns {Float32Array} */\nfunction normalizedRotation(m) {\n const out = mat3.fromMat4(new Float32Array(9), m)\n for (let c = 0; c < 3; c++) {\n const len = Math.hypot(out[c * 3], out[c * 3 + 1], out[c * 3 + 2]) || 1\n out[c * 3] /= len\n out[c * 3 + 1] /= len\n out[c * 3 + 2] /= len\n }\n return out\n}\n\n/** A node for grouping others - nothing more. */\nexport class Group extends Node {\n static type = 'group'\n}\n","import * as mat4 from '../math/mat4.js'\nimport { Color } from '../value/Color.js'\nimport { Euler } from '../value/Euler.js'\nimport { Quat } from '../value/Quat.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { checkNumber, checkOneOf, describe, fail } from '../validate.js'\nimport { resolveGeometry, resolveMaterial } from '../resolve.js'\nimport { NODE_OPTIONS, Node } from './Node.js'\n\n/** @import { Box3 } from '../value/Box3.js' */\n/** @import { Geometry } from '../geometry/Geometry.js' */\n/** @import { Material, MaterialOptions } from '../material/Material.js' */\n/** @import { GeometryOptions } from '../geometry/Geometry.js' */\n/** @import { NodeOptions } from './Node.js' */\n/** @import { ColorInput, QuatInput, Vec3Input } from '../types.js' */\n\n/**\n * @typedef {NodeOptions & {\n * geometry: Geometry | GeometryOptions,\n * material?: Material | MaterialOptions,\n * castShadow?: boolean,\n * receiveShadow?: boolean,\n * renderOrder?: number,\n * frustumCulled?: boolean,\n * data?: unknown,\n * }} DrawableOptions\n * data: what this node shows - picking hands it back as hit.datum. An array is one row per instance\n * (InstancedMesh), point (Points) or segment (Lines); on a Mesh, an array as long as its vertices is\n * a row per vertex, and a hit gives the nearest vertex's row (a surface).\n */\n\n/**\n * Where a label sits and how it competes for space.\n * @typedef {object} LabelPlacement\n * @property {LabelPlace} [place] where the label goes relative to its point (default 'center')\n * @property {[number, number]} [offset] extra shift in CSS pixels, +y down (default [0, 0])\n * @property {string} [className] CSS class(es) for the label element\n * @property {number} [priority] when labels overlap, the higher priority stays (default 0)\n * @property {'hide' | 'dim' | 'show'} [overlap] when the label is covered - by a higher-priority label, or by\n * geometry with occlude - 'hide' drops it, 'dim' draws it faint and behind; 'show' always shows it (default 'hide')\n * @property {boolean} [occlude] the label counts as covered when geometry is in front of its point (default false)\n * @property {boolean} [leader] a line from the label's point to the label, with a dot on the point - for\n * callouts set off to the side with offset, as on a diagram (default false). It takes the label's text\n * colour; style it with CSS on .phoria-leader\n * @property {'left' | 'right' | null} [edge] set the label at the view's left or right edge, level with its\n * point - callouts in a column down the side of a diagram, with leader: true. offset then moves it in from\n * the edge and up or down (default null: by its point)\n * @property {number} [minScale] show the label only when zoomed in this far: at least this many CSS pixels to\n * one world unit, at the label's point - details that appear as you come closer (default 0: always)\n */\n/** @typedef {'center' | 'above' | 'below' | 'left' | 'right'} LabelPlace */\n\n/**\n * One label per instance or point, from its row of data - or a list of these, for several each (a symbol\n * always, its details when zoomed in).\n * @typedef {Omit<LabelPlacement, 'priority'> & {\n * text: (datum: any, index: number) => string | number | null | undefined,\n * priority?: number | ((datum: any, index: number) => number),\n * at?: 'top' | 'center',\n * }} InstanceLabels\n * text: the label for a row - return null for none. priority: a number, or one per row (say, by\n * status, so problems win the space). at: the instance's top (default) or centre; points always\n * label the point itself.\n */\n\nexport const LABEL_PLACES = /** @type {LabelPlace[]} */ (['center', 'above', 'below', 'left', 'right'])\nconst PLACEMENT_OPTIONS = ['place', 'offset', 'className', 'priority', 'overlap', 'occlude', 'leader', 'edge', 'minScale']\nconst LABEL_HINTS = {\n line: 'use leader: true - a line from the point to the label',\n callout: \"use leader: true, with edge: 'left' | 'right' to line the labels up down the side\",\n column: \"use edge: 'left' | 'right' - the label sits at that edge of the view, level with its point\",\n align: \"use edge: 'left' | 'right' - the label sits at that edge of the view, level with its point\",\n pointer: 'use leader: true - a line from the point to the label',\n anchor: \"use place: 'center' | 'above' | 'below' | 'left' | 'right' (where the label goes)\",\n zIndex: \"use 'priority': higher stays when labels overlap\",\n minZoom: \"use 'minScale': CSS pixels to one world unit at the label's point\",\n lod: \"use 'minScale': the label shows when zoomed in at least this far (CSS pixels to one world unit)\",\n collision: \"use overlap: 'hide' | 'dim' | 'show'\",\n}\n// labels per instance or point take one more: they can't be moved anywhere but by offset\nconst INSTANCE_LABEL_HINTS = { ...LABEL_HINTS, position: 'labels per instance sit on their instance - offset moves them in pixels' }\n\n/**\n * Validated placement options, with defaults filled in.\n * @param {string} owner @param {Record<string, any>} o\n * @returns {Required<LabelPlacement>}\n */\nfunction placement(owner, o) {\n const offset = o.offset ?? [0, 0]\n if (!Array.isArray(offset) || offset.length !== 2 || !offset.every(Number.isFinite)) {\n fail(owner, `'offset' must be [x, y] in pixels, got ${describe(offset)}`)\n }\n return {\n place: o.place === undefined ? 'center' : checkOneOf(owner, 'place', o.place, LABEL_PLACES),\n offset: /** @type {[number, number]} */ ([offset[0], offset[1]]),\n className: o.className ? String(o.className) : '',\n priority: o.priority === undefined ? 0 : checkNumber(owner, 'priority', o.priority),\n overlap: o.overlap === undefined ? 'hide' : checkOneOf(owner, 'overlap', o.overlap, ['hide', 'dim', 'show']),\n occlude: !!o.occlude,\n leader: !!o.leader,\n edge: o.edge == null ? null : /** @type {'left' | 'right'} */ (checkOneOf(owner, 'edge', o.edge, ['left', 'right'])),\n minScale: o.minScale === undefined ? 0 : minScale(owner, o.minScale),\n }\n}\n\n/** @param {string} owner @param {unknown} v @returns {number} */\nfunction minScale(owner, v) {\n const n = checkNumber(owner, 'minScale', v)\n if (!(n >= 0)) fail(owner, `'minScale' is CSS pixels to one world unit, 0 or more, got ${n}`)\n return n\n}\n\n/** @typedef {InstanceLabels & Required<Omit<LabelPlacement, 'priority'>> & { priority: number | ((datum: any, index: number) => number) }} CheckedLabels */\n\n/** @param {string} owner @param {unknown} v @returns {CheckedLabels | CheckedLabels[] | null} */\nfunction instanceLabels(owner, v) {\n if (v == null) return null\n if (Array.isArray(v)) {\n if (!v.length) fail(owner, \"'labels' as a list needs at least one { text: (datum, index) => string, ... }\")\n return v.map((one) => /** @type {CheckedLabels} */ (instanceLabels(owner, one)))\n }\n if (typeof v !== 'object' || typeof (/** @type {any} */ (v)).text !== 'function') {\n fail(owner, `'labels' must be { text: (datum, index) => string, ... }, got ${describe(v)}`)\n }\n const o = /** @type {Record<string, any>} */ (v)\n for (const key of Object.keys(o)) {\n if (key !== 'text' && key !== 'at' && !PLACEMENT_OPTIONS.includes(key)) {\n fail(owner, `unknown labels option '${key}'${INSTANCE_LABEL_HINTS[key] ? ` - ${INSTANCE_LABEL_HINTS[key]}` : ` - expected text, at, ${PLACEMENT_OPTIONS.join(', ')}`}`)\n }\n }\n const at = o.at === undefined ? 'top' : checkOneOf(owner, 'labels.at', o.at, ['top', 'center'])\n const byRow = typeof o.priority === 'function'\n const style = placement(owner, byRow ? { ...o, priority: 0 } : o)\n return { text: o.text, at, ...style, priority: byRow ? o.priority : style.priority }\n}\n\nconst DRAWABLE_OPTIONS = [...NODE_OPTIONS, 'geometry', 'material', 'castShadow', 'receiveShadow', 'renderOrder', 'frustumCulled', 'data']\n\nconst DRAWABLE_HINTS = {\n mesh: \"pass 'geometry' and 'material' directly\",\n materials: \"one 'material' per node - use a Group of meshes for several\",\n rows: \"use 'data' - one row per instance or point\",\n}\n\n/** Base for nodes with geometry and a material: Mesh, InstancedMesh, Points and Lines. */\nexport class Drawable extends Node {\n static OPTIONS = DRAWABLE_OPTIONS\n static HINTS = DRAWABLE_HINTS\n\n /** @type {Geometry} */ #geometry\n /** @type {Material} */ #material\n castShadow = false\n receiveShadow = false\n /** Draw order override within its pass; lower first. */\n renderOrder = 0\n /** Skip drawing when outside the camera's view. */\n frustumCulled = true\n /** What this node shows: one row per instance or point for InstancedMesh and Points. Picking returns it as hit.datum. */\n data = /** @type {any} */ (null)\n\n /** @param {DrawableOptions} options */\n constructor(options) {\n super(options)\n const owner = this.constructor.name\n if (!options || options.geometry === undefined) {\n fail(owner, `'geometry' is required, e.g. new ${owner}({ geometry: box(1), material: { color: 'orange' } })`)\n }\n this.#geometry = resolveGeometry(options.geometry, owner)\n this.#material = resolveMaterial(options.material)\n if (options.castShadow !== undefined) this.castShadow = !!options.castShadow\n if (options.receiveShadow !== undefined) this.receiveShadow = !!options.receiveShadow\n if (options.renderOrder !== undefined) this.renderOrder = checkNumber(owner, 'renderOrder', options.renderOrder)\n if (options.frustumCulled !== undefined) this.frustumCulled = !!options.frustumCulled\n if (options.data !== undefined) this.data = options.data\n this.checkGeometry()\n }\n\n /** What it draws. Assign a Geometry, or a description of one; it is checked as the constructor checks it. @returns {Geometry} */\n get geometry() { return this.#geometry }\n /** @param {Geometry | import('../geometry/Geometry.js').GeometryOptions} v */\n set geometry(v) {\n this.#geometry = resolveGeometry(v, this.constructor.name)\n this.checkGeometry()\n }\n\n /** How it looks. Assign a Material, or its options - mesh.material = { color: 'red' } makes one. @returns {Material} */\n get material() { return this.#material }\n /** @param {Material | import('../material/Material.js').MaterialOptions} v */\n set material(v) { this.#material = resolveMaterial(v) }\n\n /** @internal\n * The data for a hit: this node's row at `index` when data is an array and the node draws many\n * things (instances, points, line segments), otherwise the data itself.\n * @param {number | null} index\n * @returns {any}\n */\n datumAt(index) {\n const many = 'instanceMatrices' in this || this.drawMode !== 'triangles'\n if (many && Array.isArray(this.data)) return index === null ? null : this.data[index] ?? null\n return this.data ?? null\n }\n\n /** True for anything with geometry and a material - lets renderers test without importing this class. */\n get isDrawable() {\n return true\n }\n\n /** How the geometry is drawn: 'triangles', 'points' or 'lines'. @returns {'triangles' | 'points' | 'lines'} */\n get drawMode() {\n return 'triangles'\n }\n\n /** @internal Subclasses check the geometry suits them. */\n checkGeometry() {}\n\n /** @internal @param {Box3} box */\n expandBounds(box) {\n if (!this.geometry.vertexCount) return box\n const own = this.geometry.bounds.clone().applyMatrix4(this.worldMatrix)\n box.union(padForHooks(own, this.material))\n return box\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return {\n ...super.cloneOptions(),\n geometry: this.geometry,\n material: this.material,\n castShadow: this.castShadow,\n receiveShadow: this.receiveShadow,\n renderOrder: this.renderOrder,\n frustumCulled: this.frustumCulled,\n data: this.data,\n }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = { geometry: this.geometry.toJSON(), material: this.material.toJSON() }\n if (this.castShadow) json.castShadow = true\n if (this.receiveShadow) json.receiveShadow = true\n if (this.renderOrder) json.renderOrder = this.renderOrder\n if (!this.frustumCulled) json.frustumCulled = false\n if (this.data != null) json.data = this.data\n return json\n }\n\n /** Release this node's geometry, material and textures from the GPU (and its children's). */\n dispose() {\n this.geometry.dispose()\n this.material.dispose()\n for (const [, t] of this.material.allTextures) t.dispose()\n super.dispose()\n }\n}\n\n/** Triangles: the usual solid object. */\nexport class Mesh extends Drawable {\n static type = 'mesh'\n\n /** @internal */\n checkGeometry() {\n const n = this.geometry.elementCount\n if (n % 3 !== 0) {\n fail('Mesh', `geometry has ${n} ${this.geometry.indices ? 'indices' : 'vertices'}, not a multiple of 3 - ` +\n 'triangles need three each (use Lines for pairs, Points for single vertices)')\n }\n }\n}\n\n/**\n * @typedef {object} InstanceOptions\n * @property {Vec3Input} [position]\n * @property {Vec3Input | Euler} [rotation] Euler angles in radians, XYZ order\n * @property {QuatInput} [quaternion] [x, y, z, w] or { x, y, z, w } - as physics engines give them\n * @property {Vec3Input | number} [scale]\n * @property {ColorInput} [color] multiplies the material colour\n */\n\nconst INSTANCE_OPTIONS = new Set(['position', 'rotation', 'quaternion', 'scale', 'color'])\n// reused by setInstance, so updating every instance of a large mesh each frame allocates nothing\nconst scratch = { position: new Vec3(), scale: new Vec3(), quaternion: new Quat(), rotation: new Euler() }\nconst SCRATCH_COLOR = new Color()\nconst scratchMatrix = new Float32Array(16)\n\n/**\n * True when an instance is scaled to nothing - hidden: it draws nothing, takes no room in its mesh's\n * bounds and shows no label.\n * @internal @param {ArrayLike<number>} m instance matrices @param {number} i\n */\nexport function hiddenInstance(m, i) {\n const o = i * 16\n return !m[o] && !m[o + 1] && !m[o + 2] && !m[o + 4] && !m[o + 5] && !m[o + 6] && !m[o + 8] && !m[o + 9] && !m[o + 10]\n}\n\n/**\n * Many copies of one geometry and material, drawn together. Set each copy with setInstance().\n * Picking reports which instance was hit. An instance scaled to 0 is hidden - it draws nothing, and\n * framing, culling, shadows and labels leave it out - so a pool of instances can keep spares.\n */\nexport class InstancedMesh extends Mesh {\n static type = 'instanced-mesh'\n static get OPTIONS() { return [...DRAWABLE_OPTIONS, 'count', 'instances', 'instanceMatrices', 'instanceColors', 'labels'] }\n\n /** How many instances are drawn (at most the count it was created with). */\n count = 0\n /** A 4x4 matrix per instance. @type {Float32Array} */\n instanceMatrices\n /** Linear rgb per instance, or null until a colour is set. @type {Float32Array | null} */\n instanceColors = null\n /** @internal Bumped when instance data changes, so renderers re-upload. */\n version = 0\n /** A label per instance from its row of data - or a list of them, several per instance. @type {ReturnType<typeof instanceLabels>} */\n labels = null\n\n /**\n * @param {DrawableOptions & { count?: number, instances?: InstanceOptions[], instanceMatrices?: ArrayLike<number>,\n * instanceColors?: ArrayLike<number>, labels?: InstanceLabels | InstanceLabels[] | null }} options count defaults to the number\n * of instances or rows of data; instanceMatrices/instanceColors are raw data, as toJSON() writes\n */\n constructor(options) {\n super(options)\n this.labels = instanceLabels('InstancedMesh', options.labels)\n const count = options.count ?? options.instances?.length ?? (Array.isArray(options.data) ? options.data.length : undefined)\n if (!Number.isInteger(count) || count < 0) fail('InstancedMesh', `'count' must be a whole number, got ${describe(count)}`)\n this.count = count\n this.instanceMatrices = new Float32Array(count * 16)\n // identity matrices: just the diagonal, written straight in\n const m = this.instanceMatrices\n for (let o = 0; o < m.length; o += 16) m[o] = m[o + 5] = m[o + 10] = m[o + 15] = 1\n options.instances?.forEach((inst, i) => this.setInstance(i, inst))\n if (options.instanceMatrices) {\n if (options.instanceMatrices.length !== count * 16) fail('InstancedMesh', `'instanceMatrices' needs ${count * 16} numbers (16 per instance)`)\n this.instanceMatrices.set(options.instanceMatrices)\n }\n if (options.instanceColors) {\n if (options.instanceColors.length !== count * 3) fail('InstancedMesh', `'instanceColors' needs ${count * 3} numbers (linear rgb per instance)`)\n this.instanceColors = Float32Array.from(options.instanceColors)\n }\n }\n\n /**\n * Set an instance's transform and optional colour. Unset transform parts default to identity.\n * @param {number} i\n * @param {InstanceOptions} options\n * @returns {this}\n */\n setInstance(i, options) {\n this.#checkIndex(i)\n for (const key in options) {\n if (!INSTANCE_OPTIONS.has(key)) fail('InstancedMesh', `unknown instance option '${key}' - expected position, rotation, quaternion, scale or color`)\n }\n const { position, scale, quaternion: q } = scratch\n if (options.position !== undefined) position.copy(options.position, 'InstancedMesh')\n else position.set(0, 0, 0)\n if (options.scale !== undefined) {\n if (typeof options.scale === 'number') scale.set(options.scale, options.scale, options.scale)\n else scale.copy(options.scale, 'InstancedMesh')\n } else scale.set(1, 1, 1)\n q.set(0, 0, 0, 1)\n if (options.quaternion) q.copy(options.quaternion, 'InstancedMesh').normalize()\n else if (options.rotation) {\n const r = options.rotation instanceof Euler ? options.rotation : scratch.rotation.copy(/** @type {any} */ (options.rotation), 'InstancedMesh')\n q.setFromEuler(r.x, r.y, r.z)\n }\n mat4.fromRotationTranslationScale(this.instanceMatrices.subarray(i * 16, i * 16 + 16), q, position, scale)\n if (options.color !== undefined) this.#setColor(i, options.color)\n this.version++\n return this\n }\n\n /**\n * Say instanceMatrices or instanceColors were written directly - the fast path for large data:\n * write the arrays (16 numbers a matrix, column-major; linear rgb), then call this once.\n *\n * const m = bars.instanceMatrices\n * for (let i = 0; i < n; i++) m[i * 16 + 5] = heights[i] // y scale\n * bars.needsUpdate()\n * @returns {this}\n */\n needsUpdate() {\n this.version++\n return this\n }\n\n /**\n * Set just an instance's colour, leaving its transform alone - for highlighting a picked instance.\n * @param {number} i\n * @param {ColorInput} color multiplies the material colour\n * @returns {this}\n */\n setColor(i, color) {\n this.#checkIndex(i)\n this.#setColor(i, color)\n this.version++\n return this\n }\n\n /** @param {number} i */\n #checkIndex(i) {\n if (!Number.isInteger(i) || i < 0 || i >= this.instanceMatrices.length / 16) {\n fail('InstancedMesh', `instance ${describe(i)} is out of range 0-${this.instanceMatrices.length / 16 - 1}`)\n }\n }\n\n /** @param {number} i @param {ColorInput} color */\n #setColor(i, color) {\n if (!this.instanceColors) this.instanceColors = new Float32Array(this.instanceMatrices.length / 16 * 3).fill(1)\n this.instanceColors.set(SCRATCH_COLOR.set(color, 'InstancedMesh'), i * 3)\n }\n\n /** @internal @param {Box3} box */\n expandBounds(box) {\n // as far as a shader hook can move a vertex, round each copy\n const pad = this.material.shader?.vertex ? this.material.shader.bounds ?? 0 : 0\n this.eachInstanceBox((x0, y0, z0, x1, y1, z1) => {\n box.expandByXYZ(x0 - pad, y0 - pad, z0 - pad)\n box.expandByXYZ(x1 + pad, y1 + pad, z1 + pad)\n })\n return box\n }\n\n /**\n * @internal Each instance's world box, as its low and high corners - for fitting a view round the\n * instances themselves rather than the box round them all.\n * @param {(x0: number, y0: number, z0: number, x1: number, y1: number, z1: number) => void} fn\n */\n eachInstanceBox(fn) {\n if (!this.count || !this.geometry.vertexCount) return\n const local = this.geometry.bounds\n // each instance's box from the geometry's centre and half size: the centre moves with the\n // matrix, and the half size grows by the matrix's absolute values - no allocation per instance\n const cx = (local.min[0] + local.max[0]) / 2, cy = (local.min[1] + local.max[1]) / 2, cz = (local.min[2] + local.max[2]) / 2\n const ex = (local.max[0] - local.min[0]) / 2, ey = (local.max[1] - local.min[1]) / 2, ez = (local.max[2] - local.min[2]) / 2\n const w = this.worldMatrix, im = this.instanceMatrices, m = scratchMatrix\n for (let i = 0; i < this.count; i++) {\n if (hiddenInstance(im, i)) continue\n mat4.multiply(m, w, im.subarray(i * 16, i * 16 + 16))\n const x = m[0] * cx + m[4] * cy + m[8] * cz + m[12]\n const y = m[1] * cx + m[5] * cy + m[9] * cz + m[13]\n const z = m[2] * cx + m[6] * cy + m[10] * cz + m[14]\n const hx = Math.abs(m[0]) * ex + Math.abs(m[4]) * ey + Math.abs(m[8]) * ez\n const hy = Math.abs(m[1]) * ex + Math.abs(m[5]) * ey + Math.abs(m[9]) * ez\n const hz = Math.abs(m[2]) * ex + Math.abs(m[6]) * ey + Math.abs(m[10]) * ez\n fn(x - hx, y - hy, z - hz, x + hx, y + hy, z + hz)\n }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), count: this.count, labels: this.labels }\n }\n\n clone(options) {\n const copy = super.clone(options)\n copy.instanceMatrices.set(this.instanceMatrices)\n if (this.instanceColors) copy.instanceColors = this.instanceColors.slice()\n return copy\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), count: this.count, instanceMatrices: Array.from(this.instanceMatrices),\n ...(this.instanceColors ? { instanceColors: Array.from(this.instanceColors) } : {}) }\n }\n}\n\n/** Each vertex drawn as a square point sprite: star fields, particles, scatter plots. */\nexport class Points extends Drawable {\n static type = 'points'\n static get OPTIONS() { return [...DRAWABLE_OPTIONS, 'labels', 'sort'] }\n\n /** A label per point from its row of data - or a list of them, several per point. @type {ReturnType<typeof instanceLabels>} */\n labels = null\n /**\n * Draw the points back to front, furthest first, each frame - for soft points that cover what is\n * behind them (smoke, with blending 'normal'), which then layer the right way round. Drawn as squares.\n */\n sort = false\n\n /** @param {DrawableOptions & { labels?: InstanceLabels | InstanceLabels[] | null, sort?: boolean }} options */\n constructor(options) {\n super(options)\n this.labels = instanceLabels(this.constructor.name, options?.labels)\n if (options?.sort !== undefined) {\n if (typeof options.sort !== 'boolean') fail(this.constructor.name, `'sort' is true or false, got ${describe(options.sort)}`)\n this.sort = options.sort\n }\n }\n\n /**\n * @internal Drawn as squares, one a point, rather than as GL points: when the geometry gives each\n * point its own size, opacity or angle, or the points are sorted. Squares can be any size and stay\n * whole at the edge of the view.\n */\n get drawsSprites() {\n const g = this.geometry\n return this.sort || !!(g.sizes || g.opacities || g.angles)\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), labels: this.labels, sort: this.sort }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.sort ? { sort: true } : {}) }\n }\n\n /** @returns {'points'} */\n get drawMode() {\n return 'points'\n }\n}\n\nconst ARROWS = ['none', 'start', 'end', 'both']\n\n/**\n * @typedef {DrawableOptions & { arrows?: 'none' | 'start' | 'end' | 'both', arrowSize?: number }} LinesOptions\n */\n\n/**\n * Line segments: indices (or consecutive vertices) in pairs. Width is in pixels and works on\n * every platform. edges(geometry) makes a wireframe of any geometry. Segments each starting where\n * the one before ended make a chain - a polyline - which dashes run on along and arrowheads finish.\n */\nexport class Lines extends Drawable {\n static type = 'lines'\n static get OPTIONS() { return [...DRAWABLE_OPTIONS, 'arrows', 'arrowSize'] }\n\n /** Arrowheads at the ends of each chain: at its 'start', its 'end', 'both' or 'none'. @type {'none' | 'start' | 'end' | 'both'} */\n arrows = 'none'\n /** Arrowhead length in pixels; 0 sizes them from the material's width. */\n arrowSize = 0\n\n /** @param {LinesOptions} options */\n constructor(options) {\n super(options)\n if (options?.arrows !== undefined) this.arrows = /** @type {any} */ (checkOneOf('Lines', 'arrows', options.arrows, ARROWS))\n if (options?.arrowSize !== undefined) this.arrowSize = Math.max(0, checkNumber('Lines', 'arrowSize', options.arrowSize))\n }\n\n /** @internal Which ends get arrowheads, for the shader: 1 the start, 2 the end. */\n get arrowBits() {\n return ARROWS.indexOf(this.arrows)\n }\n\n /** @internal An arrowhead's length in pixels, before the pixel ratio. @param {number} width */\n arrowPixels(width) {\n return this.arrowSize || 6 + width * 3\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), arrows: this.arrows, arrowSize: this.arrowSize }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.arrows !== 'none' ? { arrows: this.arrows } : {}), ...(this.arrowSize ? { arrowSize: this.arrowSize } : {}) }\n }\n\n /** @returns {'lines'} */\n get drawMode() {\n return 'lines'\n }\n\n /** @internal */\n checkGeometry() {\n const n = this.geometry.elementCount\n if (n % 2 !== 0) fail('Lines', `geometry has ${n} ${this.geometry.indices ? 'indices' : 'vertices'} - segments need them in pairs`)\n }\n}\n\n/**\n * @typedef {NodeOptions & LabelPlacement & { text: string | number }} LabelOptions\n */\n\n/**\n * HTML text pinned to a 3D position: crisp at any pixel ratio and styleable with CSS. Hidden when\n * behind the camera or invisible.\n */\nexport class Label extends Node {\n static type = 'label'\n static get OPTIONS() { return [...NODE_OPTIONS, 'text', ...PLACEMENT_OPTIONS] }\n static get HINTS() { return LABEL_HINTS }\n\n text = ''\n /** CSS class(es) for the label element. */\n className = ''\n /** Where the label goes relative to its point. @type {LabelPlace} */\n place = 'center'\n /** Extra shift in CSS pixels, +y down. @type {[number, number]} */\n offset = [0, 0]\n /** When labels overlap, the higher priority stays. */\n priority = 0\n /** When covered by a higher-priority label (or geometry, with occlude): 'hide' drops it, 'dim' fades it, 'show' always shows it. @type {'hide' | 'dim' | 'show'} */\n overlap = 'hide'\n /** The label counts as covered when geometry is in front of its point. */\n occlude = false\n /** A line from the label's point to the label, for callouts. */\n leader = false\n /** Set at the view's left or right edge, level with its point, or null for by its point. @type {'left' | 'right' | null} */\n edge = null\n /** Shown only when zoomed in this far: CSS pixels to one world unit at its point; 0 for always. */\n minScale = 0\n\n /** @param {LabelOptions} options */\n constructor(options) {\n super(options)\n if (typeof options?.text !== 'string' && typeof options?.text !== 'number') {\n fail('Label', `'text' is required, got ${describe(options?.text)}`)\n }\n this.text = String(options.text)\n Object.assign(this, placement('Label', options))\n }\n\n /** @internal Lets renderers spot labels without importing this class. */\n get isLabel() {\n return true\n }\n\n /** @internal A label counts as the point it is pinned to, so framing leaves room for axis ticks and titles. @param {Box3} box */\n expandBounds(box) {\n return box.expandByPoint(this.worldPosition)\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), text: this.text, className: this.className, place: this.place,\n offset: [...this.offset], priority: this.priority, overlap: this.overlap, occlude: this.occlude, leader: this.leader, edge: this.edge,\n minScale: this.minScale }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = { text: this.text }\n if (this.className) json.className = this.className\n if (this.place !== 'center') json.place = this.place\n if (this.offset[0] || this.offset[1]) json.offset = [...this.offset]\n if (this.priority) json.priority = this.priority\n if (this.overlap !== 'hide') json.overlap = this.overlap\n if (this.occlude) json.occlude = true\n if (this.leader) json.leader = true\n if (this.edge) json.edge = this.edge\n if (this.minScale) json.minScale = this.minScale\n return json\n }\n}\n\n/**\n * A drawable's world box, grown by as far as its shader's vertex hook says it can move a vertex.\n * @param {import('../value/Box3.js').Box3} box @param {import('../material/Material.js').Material} material\n */\nfunction padForHooks(box, material) {\n const pad = material.shader?.vertex ? material.shader.bounds ?? 0 : 0\n if (pad > 0 && !box.isEmpty()) {\n box.min.set(box.min[0] - pad, box.min[1] - pad, box.min[2] - pad)\n box.max.set(box.max[0] + pad, box.max[1] + pad, box.max[2] + pad)\n }\n return box\n}\n","// The renderer contract: what to draw this frame, as plain data. The scene never talks to WebGL -\n// a renderer draws a FrameDescription, so renderers are replaceable and frames testable without a GPU.\nimport { Mat4 } from './value/Mat4.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { Box3 } from './value/Box3.js'\nimport { warnOnce } from './validate.js'\nimport { fitPointShadow, fitShadow, fitSpotShadow, SPOT_TILES } from './shadow.js'\nimport { worldPlane } from './clip.js'\nimport { hiddenInstance } from './scene/drawables.js'\n\n/** @import { Scene } from './scene/Scene.js' */\n/** @import { Camera } from './scene/cameras.js' */\n/** @import { Node } from './scene/Node.js' */\n/** @import { Color } from './value/Color.js' */\n/** @import { Texture } from './material/Texture.js' */\n/** @import { Geometry } from './geometry/Geometry.js' */\n/** @import { Material } from './material/Material.js' */\n/** @import { Drawable, InstancedMesh, Label, LabelPlacement } from './scene/drawables.js' */\n/** @import { Light, HemisphereLight, DirectionalLight, PointLight, SpotLight } from './scene/lights.js' */\n\n// Nodes are told apart by markers (isDrawable, isLabel, lightKind) rather than instanceof, so\n// collecting a frame doesn't pull every node class into an app's bundle.\n\n/** Per-scene light limits for the WebGL 2 renderer; extras are dropped with a warning. */\nexport const LIGHT_LIMITS = { punctual: 4, directional: 2 }\n\n/**\n * @typedef {object} FrameLight\n * @property {'ambient' | 'hemisphere' | 'directional' | 'point' | 'spot'} kind\n * @property {Node} node\n * @property {Color} color\n * @property {number} intensity\n * @property {Color} [ground] hemisphere\n * @property {Vec3} [position] point, spot (world)\n * @property {Vec3} [direction] directional, spot (world, the way the light travels)\n * @property {number} [range] point, spot (0 = unlimited)\n * @property {number} [angle] spot\n * @property {number} [penumbra] spot\n * @property {boolean} [castShadow] directional, spot, point\n * @property {number} [shadowTile] spot: which spot shadow is its, or -1\n */\n\n/**\n * The section plane cutting a drawable, from the nearest clip above it.\n * @typedef {object} FrameClip\n * @property {Float32Array} plane [nx, ny, nz, d] in world space, unit normal: cut away where n.p + d > 0\n * @property {Color | null} cap fill colour for cut faces (linear), or null for none\n */\n\n/**\n * A subtree to outline: the meshes in it, drawn together, so the line runs round their joint silhouette.\n * @typedef {object} FrameOutline\n * @property {Color} color linear\n * @property {number} width CSS pixels\n * @property {DrawItem[]} items\n */\n\n/**\n * A section plane's cap: the cut faces of the solids under one clip, filled in its colour. The\n * renderer finds where the plane passes through solid by counting each pixel's faces into the\n * stencil buffer, then fills those pixels with the plane - drawn where it is, so nothing in the\n * same plane fights it, and what is inside the solids stays hidden.\n * @typedef {object} FrameCap\n * @property {Float32Array} plane [nx, ny, nz, d], as the clip's\n * @property {Color} color linear\n * @property {DrawItem[]} items the opaque meshes under the clip, as drawn\n * @property {Vec3} center a point on the plane in the middle of the cut\n * @property {number} radius how far from center the cut reaches, at most\n */\n\n/**\n * @typedef {object} DrawItem\n * @property {Drawable} node\n * @property {Geometry} geometry\n * @property {Material} material\n * @property {Mat4} worldMatrix\n * @property {InstancedMesh | null} instances\n * @property {number} depth view-space distance of the bounds centre, for sorting\n * @property {FrameClip | null} clip the plane cutting it, if any\n */\n\n/**\n * @typedef {object} FrameLabel\n * @property {any} key stable identity across frames: the Label node, or a key per instance or point\n * @property {Node} node the Label, or the InstancedMesh or Points it labels\n * @property {number | null} index the instance or point, for labels made from `labels`\n * @property {string} text\n * @property {Required<LabelPlacement>} style\n * @property {Vec3} position world\n * @property {[number, number]} ndc [x, y] in -1..1\n * @property {number} depth\n * @property {boolean} visible in front of the camera and inside the view\n * @property {number} scale how far zoomed in at the point: half the view's height, in world units, is 1 / scale -\n * the layer turns it into pixels to one world unit, for minScale\n */\n\n/**\n * The shadow-casting directional light's view of the scene: what to draw into its depth map.\n * @typedef {object} ShadowFrame\n * @property {FrameLight} light\n * @property {Mat4} viewProjection world to the light's clip space\n * @property {number} texelSize world units per shadow map texel\n * @property {DrawItem[]} casters drawn into the map, whether or not the camera sees them\n */\n\n/**\n * A spot light's view of the scene for its shadow: its tile in the spot shadow map.\n * @typedef {object} SpotShadowFrame\n * @property {FrameLight} light\n * @property {number} tile 0 - 3\n * @property {Mat4} viewProjection world to the light's clip space\n * @property {number} texelAngle a shadow map texel's size at a distance of 1, for the bias\n * @property {DrawItem[]} casters what it draws, culled to the light's view\n */\n\n/**\n * A point light's view of the scene for its shadow: six faces of a cube round it.\n * @typedef {object} PointShadowFrame\n * @property {FrameLight} light\n * @property {{ viewProjection: Mat4, casters: DrawItem[] }[]} faces +X, -X, +Y, -Y, +Z, -Z, each with what it sees\n * @property {number} near\n * @property {number} far\n * @property {number} texelAngle a texel's size at a distance of 1, for the bias\n */\n\n/**\n * The hovered thing to tint: a whole node, or one of its instances or points - or, under a node with\n * highlightWhole, every drawable in that subtree.\n * @typedef {object} FrameHighlight\n * @property {Node} node\n * @property {number | null} index instance (InstancedMesh) or point (Points); null for the whole node\n * @property {Set<Node> | null} [nodes] every drawable tinted, when a highlightWhole subtree is tinted as one\n * @property {Color} color linear\n * @property {number} amount 0-1, how far the colour moves towards it\n */\n\n/**\n * @typedef {object} FrameDescription\n * @property {{ view: Mat4, projection: Mat4, viewProjection: Mat4, position: Vec3, near: number, far: number, camera: Camera }} camera\n * @property {FrameLight[]} lights\n * @property {DrawItem[]} opaque sorted by renderOrder, then material variant, then front to back\n * @property {DrawItem[]} transparent sorted by renderOrder, then back to front\n * @property {FrameLabel[]} labels\n * @property {Color | Texture | null} background\n * @property {Scene['environment']} environment\n * @property {number} environmentIntensity\n * @property {number} backgroundBlur 0-1\n * @property {import('./fog.js').Fog | null} fog distance fog\n * @property {ShadowFrame | null} shadow the shadow-casting light's view, when there is one and something casts\n * @property {SpotShadowFrame[]} spotShadows spot lights' shadows, up to four\n * @property {PointShadowFrame | null} pointShadow a point light's shadow, all round it\n * @property {FrameCap[]} caps section planes' caps to fill, after the opaque pass\n * @property {{ drawn: number, culled: number }} stats\n * @property {number} [time] the View's clock in seconds, for shader hooks that read uTime\n * @property {FrameHighlight | null} highlight set by the View for hover highlighting\n * @property {any[]} overlays HTML elements carried by the nodes drawn (node.overlay)\n * @property {boolean} interactive some node has a tooltip, highlight or pointer handler\n * @property {boolean} draggable some node has an onDrag handler\n * @property {FrameOutline[]} outlines subtrees to draw an outline round, last of all\n * @property {boolean} tooltips some node has its own tooltip\n */\n\n/**\n * What to draw: everything visible, culled to the camera's view, sorted for drawing. Expects world\n * matrices to be current (scene.update() or scene.updateWorld()); the camera is brought up to date\n * here, since it often isn't in the scene.\n * @param {Scene} scene\n * @param {Camera} camera\n * @returns {FrameDescription}\n */\nexport function collect(scene, camera) {\n camera.updateWorld()\n const view = camera.viewMatrix\n const projection = camera.projectionMatrix\n const viewProjection = new Mat4().multiplyMatrices(projection, view)\n const planes = frustumPlanes(viewProjection)\n\n /** @type {FrameDescription} */\n const frame = {\n camera: { view, projection, viewProjection, position: camera.worldPosition, near: camera.near, far: camera.far, camera },\n lights: [],\n opaque: [],\n transparent: [],\n labels: [],\n background: scene.background,\n environment: scene.environment,\n environmentIntensity: scene.environmentIntensity,\n backgroundBlur: scene.backgroundBlur,\n fog: scene.fog,\n shadow: null,\n spotShadows: [],\n pointShadow: null,\n caps: [],\n stats: { drawn: 0, culled: 0 },\n time: 0,\n highlight: null,\n overlays: [],\n interactive: false,\n draggable: false,\n outlines: [],\n tooltips: false,\n }\n let punctual = 0, directional = 0\n // shadows: what casts (seen or not - a shadow can fall into view from off screen) and what\n // receives; only looked at further when a light casts\n /** @type {[any, FrameClip | null][]} */\n const casters = []\n /** @type {any[]} */\n const receivers = []\n // the solids under each capped clip\n /** @type {Map<FrameClip, DrawItem[]>} */\n const capped = new Map()\n\n /**\n * @param {any} node @param {FrameClip | null} clip the plane cutting this subtree, from above\n * @param {FrameOutline | null} outline the outline drawn round this subtree, from above\n */\n const visit = (node, clip, outline) => {\n // per-camera visibility decides what this frame draws, without touching the scene\n if (!node.shownTo(camera)) return\n // the nearest clip cuts this subtree\n if (node.clip) clip = { plane: worldPlane(node), cap: node.clip.cap }\n // an outline goes round everything under the node that asks for it\n if (node.outline) {\n outline = { color: node.outline.color, width: node.outline.width, items: [] }\n frame.outlines.push(outline)\n }\n if (node.overlay) frame.overlays.push(node.overlay)\n if (node.onDrag) frame.interactive = frame.draggable = true\n if (node.tooltip) frame.interactive = frame.tooltips = true\n else if (node.highlight || node.handlersFor('hover').length || node.handlersFor('click').length) frame.interactive = true\n if (node.isDrawable) {\n if (node.castShadow && node.drawMode !== 'points' && node.drawMode !== 'lines') casters.push([node, clip])\n if (node.receiveShadow) receivers.push(node)\n const item = drawItem(node, view, planes, clip)\n if (item) {\n // point sprites with a map nearly always have soft alpha edges, so they blend too\n const blended = node.material.transparent || (node.drawMode === 'points' && node.material.map)\n ;(blended ? frame.transparent : frame.opaque).push(item)\n if (outline && node.drawMode === 'triangles') outline.items.push(item)\n if (item.clip?.cap && !blended) {\n const solids = capped.get(item.clip)\n if (solids) solids.push(item)\n else capped.set(item.clip, [item])\n }\n frame.stats.drawn++\n if (node.labels) instanceLabels(node, viewProjection, view, projection[5], frame.labels)\n } else {\n frame.stats.culled++\n }\n } else if (node.isLabel) {\n const position = node.worldPosition\n frame.labels.push({ key: node, node, index: null, text: node.text, style: node, position, ...project(position, viewProjection, view, projection[5]) })\n } else if (node.lightKind) {\n addLight(/** @type {Light} */ (node))\n }\n for (const child of node.children) visit(child, clip, outline)\n }\n\n /** @param {any} node */\n const addLight = (node) => {\n const kind = node.lightKind\n if (kind === 'ambient') {\n frame.lights.push({ kind: 'ambient', node, color: node.color, intensity: node.intensity })\n } else if (kind === 'hemisphere') {\n frame.lights.push({ kind: 'hemisphere', node, color: node.sky, ground: node.ground, intensity: node.intensity })\n } else if (kind === 'directional') {\n if (++directional > LIGHT_LIMITS.directional) {\n warnOnce(scene, `more than ${LIGHT_LIMITS.directional} directional lights - the extras are ignored; use scene.environment for more light`)\n } else {\n frame.lights.push({ kind: 'directional', node, color: node.color, intensity: node.intensity, direction: node.worldDirection, castShadow: node.castShadow })\n }\n } else {\n if (++punctual > LIGHT_LIMITS.punctual) {\n warnOnce(scene, `more than ${LIGHT_LIMITS.punctual} point and spot lights - the extras are ignored`)\n } else if (kind === 'spot') {\n frame.lights.push({ kind: 'spot', node, color: node.color, intensity: node.intensity, position: node.worldPosition,\n direction: node.worldDirection, range: node.range, angle: node.angle, penumbra: node.penumbra, castShadow: node.castShadow, shadowTile: -1 })\n } else {\n frame.lights.push({ kind: 'point', node, color: node.color, intensity: node.intensity, position: node.worldPosition, range: node.range, castShadow: node.castShadow })\n }\n }\n }\n visit(scene, null, null)\n frame.outlines = frame.outlines.filter((o) => o.items.length)\n for (const [clip, items] of capped) frame.caps.push(capOf(clip, items))\n\n // one shadow map, for the first directional light that casts; it goes first, so the shader\n // knows which light the map belongs to\n const sun = frame.lights.findIndex((l) => l.kind === 'directional' && l.castShadow)\n const spots = frame.lights.filter((l) => l.kind === 'spot' && l.castShadow)\n const points = frame.lights.filter((l) => l.kind === 'point' && l.castShadow)\n const items = sun >= 0 || spots.length || points.length ? /** @type {DrawItem[]} */ (casters.map(([n, clip]) => drawItem(n, view, null, clip)).filter(Boolean)) : []\n if (spots.length > SPOT_TILES) warnOnce(scene, `more than ${SPOT_TILES} spot lights cast shadows - the extras don't`)\n if (points.length > 1) warnOnce(scene, 'more than one point light casts shadows - only the first does')\n if (items.length && points.length) {\n const light = points[0]\n const boxes = items.map((c) => c.node.expandBounds(new Box3()))\n const fit = fitPointShadow(/** @type {Vec3} */ (light.position), light.range ?? 0, boxes, receivers.map((n) => n.expandBounds(new Box3())))\n if (fit) {\n // each face draws only what it can see\n const faces = fit.viewProjections.map((viewProjection) => {\n const planes = frustumPlanes(viewProjection)\n return { viewProjection, casters: items.filter((_, i) => sphereInFrustum(planes, boxes[i].getCenter(), boxes[i].getRadius())) }\n })\n frame.pointShadow = { light, faces, near: fit.near, far: fit.far, texelAngle: fit.texelAngle }\n }\n }\n if (items.length && spots.length) {\n const boxes = items.map((c) => c.node.expandBounds(new Box3()))\n const receiving = receivers.map((n) => n.expandBounds(new Box3()))\n for (const light of spots.slice(0, SPOT_TILES)) {\n const at = /** @type {Vec3} */ (light.position)\n // the light's own fitting - a lamp round it - doesn't shadow it\n const own = boxes.map((b) => b.containsPoint(at))\n const fit = fitSpotShadow(at, /** @type {Vec3} */ (light.direction), /** @type {number} */ (light.angle), light.range ?? 0, boxes.filter((_, i) => !own[i]), receiving)\n if (!fit) continue\n const planes = frustumPlanes(fit.viewProjection)\n const seen = items.filter((item, i) => {\n if (own[i]) return false\n const box = boxes[i]\n return sphereInFrustum(planes, box.getCenter(), box.getRadius())\n })\n light.shadowTile = frame.spotShadows.length\n frame.spotShadows.push({ light, tile: light.shadowTile, viewProjection: fit.viewProjection, texelAngle: fit.texelAngle, casters: seen })\n }\n }\n if (items.length && sun >= 0) {\n const light = frame.lights[sun]\n const bounds = (/** @type {any} */ n) => n.expandBounds(new Box3())\n const fit = fitShadow(/** @type {Vec3} */ (light.direction), items.map((c) => bounds(c.node)), receivers.map(bounds), undefined, /** @type {any} */ (light.node).shadowBounds)\n if (fit) {\n frame.lights.splice(sun, 1)\n frame.lights.unshift(light)\n frame.shadow = { light, ...fit, casters: items }\n }\n }\n\n // opaque: front to back lets the depth test reject hidden pixels early; grouping by material\n // variant keeps shader switches down\n frame.opaque.sort((x, y) => x.node.renderOrder - y.node.renderOrder ||\n (x.material.variant < y.material.variant ? -1 : x.material.variant > y.material.variant ? 1 : 0) ||\n x.depth - y.depth)\n // transparent: back to front so blending composes correctly\n frame.transparent.sort((x, y) => x.node.renderOrder - y.node.renderOrder || y.depth - x.depth)\n return frame\n}\n\n/**\n * @param {Drawable} node @param {Mat4} view @param {Float32Array[] | null} planes null: no culling\n * @param {FrameClip | null} clip the plane cutting it\n * @returns {DrawItem | null} null when culled, or cut away whole\n */\nfunction drawItem(node, view, planes, clip) {\n const { geometry, material, worldMatrix } = node\n const instances = 'instanceMatrices' in node ? /** @type {InstancedMesh} */ (node) : null\n if (instances && instances.count === 0) return null\n if (!geometry.vertexCount) return null\n\n const box = geometry.bounds\n const center = box.getCenter().applyMatrix4(worldMatrix)\n const scale = Math.max(Math.hypot(worldMatrix[0], worldMatrix[1], worldMatrix[2]),\n Math.hypot(worldMatrix[4], worldMatrix[5], worldMatrix[6]), Math.hypot(worldMatrix[8], worldMatrix[9], worldMatrix[10]))\n // instanced meshes spread their copies anywhere, so they aren't culled as a whole; a shader hook\n // that moves vertices is culled by its padded bounds, or - without them - not at all\n const hooks = material.shader?.vertex ? material.shader : null\n const pad = hooks ? hooks.bounds : 0\n if (planes && node.frustumCulled && !instances && pad !== null && !sphereInFrustum(planes, center, box.getRadius() * scale + pad)) return null\n // all of it on the cut-away side of a clip - points and lines aren't cut, so they stay\n const cuts = clip && node.drawMode === 'triangles' ? clip : null\n if (cuts && !instances) {\n const p = cuts.plane\n if (p[0] * center[0] + p[1] * center[1] + p[2] * center[2] + p[3] > box.getRadius() * scale) return null\n }\n\n // distance in front of the camera, along its view direction\n const depth = -(view[2] * center[0] + view[6] * center[1] + view[10] * center[2] + view[14])\n return { node, geometry, material, worldMatrix, instances, depth, clip: cuts }\n}\n\n/**\n * Where a clip's cap goes: the middle of its solids' bounds, brought onto the plane, and how far\n * the cut can reach from there.\n * @param {FrameClip} clip @param {DrawItem[]} items\n * @returns {FrameCap}\n */\nfunction capOf(clip, items) {\n const box = new Box3()\n for (const item of items) item.node.expandBounds(box)\n const c = box.getCenter(), p = clip.plane\n const off = p[0] * c[0] + p[1] * c[1] + p[2] * c[2] + p[3]\n const center = new Vec3(c[0] - p[0] * off, c[1] - p[1] * off, c[2] - p[2] * off)\n return { plane: clip.plane, color: /** @type {Color} */ (clip.cap), items, center, radius: box.getRadius() }\n}\n\n// a stable key per labelled node, so label elements survive from frame to frame\n/** @type {WeakMap<object, number>} */\nconst ids = new WeakMap()\nlet nextId = 1\n\n/**\n * Labels for every instance or point that has text, from the node's `labels` option.\n * @param {any} node InstancedMesh or Points @param {Mat4} viewProjection @param {Mat4} view\n * @param {number} yScale the projection's vertical scale @param {FrameLabel[]} out\n */\nfunction instanceLabels(node, viewProjection, view, yScale, out) {\n // several labels per instance: the first keeps the plain key, so a single set's labels don't change identity\n if (Array.isArray(node.labels)) {\n node.labels.forEach((labels, layer) => instanceLabelSet(node, labels, layer, viewProjection, view, yScale, out))\n } else instanceLabelSet(node, node.labels, 0, viewProjection, view, yScale, out)\n}\n\n/**\n * @param {any} node @param {any} labels one set of instance labels @param {number} layer its place in the list\n * @param {Mat4} viewProjection @param {Mat4} view @param {number} yScale @param {FrameLabel[]} out\n */\nfunction instanceLabelSet(node, labels, layer, viewProjection, view, yScale, out) {\n const { worldMatrix: w } = node\n let id = ids.get(node)\n if (id === undefined) ids.set(node, id = nextId++)\n const instanced = 'instanceMatrices' in node\n const n = instanced ? node.count : node.geometry.drawnVertices\n let px = 0, py = 0, pz = 0\n if (instanced) {\n // where on each instance: the top centre or the centre of its geometry\n const box = node.geometry.bounds, c = box.getCenter()\n px = c[0]; py = labels.at === 'top' ? box.max[1] : c[1]; pz = c[2]\n }\n const data = Array.isArray(node.data) ? node.data : null\n const byRow = typeof labels.priority === 'function'\n for (let i = 0; i < n; i++) {\n // an instance scaled to nothing is hidden, and so is its label\n if (instanced && hiddenInstance(node.instanceMatrices, i)) continue\n const row = data ? data[i] : null\n const text = labels.text(row, i)\n if (text === null || text === undefined || text === '') continue\n let x, y, z\n if (instanced) {\n const m = node.instanceMatrices, o = i * 16\n x = m[o] * px + m[o + 4] * py + m[o + 8] * pz + m[o + 12]\n y = m[o + 1] * px + m[o + 5] * py + m[o + 9] * pz + m[o + 13]\n z = m[o + 2] * px + m[o + 6] * py + m[o + 10] * pz + m[o + 14]\n } else {\n const p = node.geometry.positions\n x = p[i * 3]; y = p[i * 3 + 1]; z = p[i * 3 + 2]\n }\n const position = new Vec3(\n w[0] * x + w[4] * y + w[8] * z + w[12],\n w[1] * x + w[5] * y + w[9] * z + w[13],\n w[2] * x + w[6] * y + w[10] * z + w[14])\n const style = byRow ? { ...labels, priority: labels.priority(row, i) } : labels\n out.push({ key: layer ? `${id}:${i}:${layer}` : `${id}:${i}`, node, index: i, text: String(text), style, position, ...project(position, viewProjection, view, yScale) })\n }\n}\n\n/**\n * Where a world position lands in normalised device coordinates (x, y and z, -1 to 1), and whether it\n * is in view: inside the edges, and between the near and far planes. Labels and view.project() both\n * place things with it.\n * @param {ArrayLike<number>} position @param {ArrayLike<number>} viewProjection\n * @returns {{ ndc: [number, number, number], visible: boolean }}\n */\nexport function toScreen(position, viewProjection) {\n const m = viewProjection\n const x = m[0] * position[0] + m[4] * position[1] + m[8] * position[2] + m[12]\n const y = m[1] * position[0] + m[5] * position[1] + m[9] * position[2] + m[13]\n const z = m[2] * position[0] + m[6] * position[1] + m[10] * position[2] + m[14]\n const w = m[3] * position[0] + m[7] * position[1] + m[11] * position[2] + m[15]\n const ndc = /** @type {[number, number, number]} */ ([x / w, y / w, z / w])\n return { ndc, visible: w > 0 && Math.abs(ndc[0]) <= 1 && Math.abs(ndc[1]) <= 1 && Math.abs(ndc[2]) <= 1 }\n}\n\n/**\n * A label's place on screen, and how far in front of the camera it is - along the view, in world\n * units, for both kinds of camera (an orthographic one's clip w is always 1).\n * @param {Vec3} position @param {Mat4} viewProjection @param {Mat4} view\n */\nfunction project(position, viewProjection, view, yScale) {\n const { ndc, visible } = toScreen(position, viewProjection)\n const depth = -(view[2] * position[0] + view[6] * position[1] + view[10] * position[2] + view[14])\n // clip w at the point: its depth for a perspective camera, 1 for an orthographic one\n const m = viewProjection\n const w = m[3] * position[0] + m[7] * position[1] + m[11] * position[2] + m[15]\n return { ndc: /** @type {[number, number]} */ ([ndc[0], ndc[1]]), depth, visible, scale: w > 0 ? yScale / w : 0 }\n}\n\n// The six planes (a, b, c, d with the normal pointing inwards) of a view-projection matrix.\n/** @param {Float32Array} m @returns {Float32Array[]} */\nfunction frustumPlanes(m) {\n const rows = (i) => [m[i], m[4 + i], m[8 + i], m[12 + i]]\n const r0 = rows(0), r1 = rows(1), r2 = rows(2), r3 = rows(3)\n return [\n [r3[0] + r0[0], r3[1] + r0[1], r3[2] + r0[2], r3[3] + r0[3]],\n [r3[0] - r0[0], r3[1] - r0[1], r3[2] - r0[2], r3[3] - r0[3]],\n [r3[0] + r1[0], r3[1] + r1[1], r3[2] + r1[2], r3[3] + r1[3]],\n [r3[0] - r1[0], r3[1] - r1[1], r3[2] - r1[2], r3[3] - r1[3]],\n [r3[0] + r2[0], r3[1] + r2[1], r3[2] + r2[2], r3[3] + r2[3]],\n [r3[0] - r2[0], r3[1] - r2[1], r3[2] - r2[2], r3[3] - r2[3]],\n ].map((p) => {\n const len = Math.hypot(p[0], p[1], p[2]) || 1\n return new Float32Array([p[0] / len, p[1] / len, p[2] / len, p[3] / len])\n })\n}\n\n/** @param {Float32Array[]} planes @param {ArrayLike<number>} c @param {number} radius */\nfunction sphereInFrustum(planes, c, radius) {\n for (const p of planes) {\n if (p[0] * c[0] + p[1] * c[1] + p[2] * c[2] + p[3] < -radius) return false\n }\n return true\n}\n\n/**\n * A renderer that records frames instead of drawing them - for tests, doc-tests and server-side\n * checks. Same render() contract as the WebGL renderer.\n */\nexport class NullRenderer {\n /** @type {FrameDescription | null} */\n lastFrame = null\n frameCount = 0\n\n /**\n * Bring world matrices up to date and record what would be drawn. Doesn't run update handlers -\n * the View's loop (or your own) does that with scene.update(dt, t).\n * @param {Scene} scene @param {Camera} camera\n * @returns {FrameDescription}\n */\n render(scene, camera) {\n scene.updateWorldTree()\n return this.renderFrame(collect(scene, camera))\n }\n\n /** @internal @param {FrameDescription} frame @returns {FrameDescription} */\n renderFrame(frame) {\n this.lastFrame = frame\n this.frameCount++\n return frame\n }\n\n dispose() {}\n}\n\n","// Label placement and overlap resolution, as plain arithmetic on boxes - no DOM, so it is testable\n// and the label layer stays a thin writer of styles.\n\n/** @import { LabelPlace } from './scene/drawables.js' */\n\n// gap between a point and a label placed beside it, in CSS pixels\nconst GAP = 6\n// how far labels set at an edge of the view sit in from it, in CSS pixels\nconst EDGE = 16\n// grid cell size for finding neighbours quickly\nconst CELL = 64\n// how far two labels may run into each other before one gives way: a label newly showing\n// needs to be mostly clear; one already showing holds on through more, so labels don't flicker\n// in and out as the view moves\nconst NEW_OVERLAP = 0.2\nconst KEEP_OVERLAP = 0.5\n\n/**\n * Top-left corner of a label box placed relative to its point.\n * @param {number} x @param {number} y the point, in pixels\n * @param {number} width @param {number} height the label's size\n * @param {LabelPlace} place where the label goes relative to the point\n * @param {[number, number]} offset extra shift in pixels\n * @param {'left' | 'right' | null} [edge] set at that edge of the view instead, level with the point\n * @param {number} [viewWidth] the view's width, for edge: 'right'\n * @returns {[number, number]}\n */\nexport function placeBox(x, y, width, height, place, offset, edge = null, viewWidth = 0) {\n // at an edge of the view, level with the point: offset moves it in from the edge, and up or down\n if (edge) return [edge === 'left' ? EDGE + offset[0] : viewWidth - EDGE - width - offset[0], y - height / 2 + offset[1]]\n let left = x - width / 2, top = y - height / 2\n if (place === 'above') top = y - height - GAP\n else if (place === 'below') top = y + GAP\n else if (place === 'left') left = x - width - GAP\n else if (place === 'right') left = x + GAP\n return [left + offset[0], top + offset[1]]\n}\n\n/**\n * Space out the labels in a column at an edge of the view, so callouts never overlap: in each\n * column they keep the order of their points, top to bottom, at least `gap` apart. Labels that would\n * run into each other move as a group, centred where they wanted to be on average - so each stays\n * as near its point as it can - and the group is kept inside the view. Changes each box's top.\n * @param {{ top: number, height: number, edge?: 'left' | 'right' | null }[]} boxes\n * @param {number} height the view's height\n * @param {number} [gap]\n */\nexport function stackColumns(boxes, height, gap = 4) {\n for (const side of ['left', 'right']) {\n const column = boxes.filter((b) => b.edge === side).sort((a, b) => a.top - b.top)\n /** @type {{ items: typeof column, wants: number[], top: number, height: number }[]} */\n const groups = []\n for (const box of column) {\n let group = { items: [box], wants: [box.top], top: box.top, height: box.height }\n // merge with the group above while they would overlap\n while (groups.length) {\n const above = groups[groups.length - 1]\n if (above.top + above.height + gap <= group.top) break\n groups.pop()\n const items = [...above.items, ...group.items], wants = [...above.wants, ...group.wants]\n let offset = 0, shift = 0\n for (let i = 0; i < items.length; i++) {\n shift += wants[i] - offset\n offset += items[i].height + gap\n }\n const total = offset - gap\n group = { items, wants, top: Math.min(Math.max(shift / items.length, 0), Math.max(0, height - total)), height: total }\n }\n groups.push(group)\n }\n for (const group of groups) {\n let top = group.top\n for (const box of group.items) {\n box.top = top\n top += box.height + gap\n }\n }\n }\n}\n\n/**\n * Line up each column of labels at an edge of the view: every label in it as wide as the widest, the\n * right column's moved in to keep its right side at the edge - so their leaders all start from the\n * same line and none runs under a neighbour. Changes each box's width (and left, on the right).\n * @param {{ left: number, width: number, edge?: 'left' | 'right' | null }[]} boxes\n */\nexport function alignColumns(boxes) {\n for (const side of ['left', 'right']) {\n const column = boxes.filter((b) => b.edge === side)\n const widest = Math.max(0, ...column.map((b) => b.width))\n for (const b of column) {\n if (side === 'right') b.left -= widest - b.width\n b.width = widest\n }\n }\n}\n\n/**\n * Where a leader line from a label's point meets its box: the nearest point of the box, or null\n * when the point is in (or touching) the box and needs no line. A callout in a column at an edge is\n * met at the inner end of its bottom edge, where an underline ends - and always gets its line.\n * @param {number} x @param {number} y the point\n * @param {{ left: number, top: number, width: number, height: number }} box\n * @param {'left' | 'right' | null} [edge]\n * @param {number} [rule] the thickness of its underline (its bottom border), whose middle the line meets\n * @returns {[number, number] | null}\n */\nexport function leaderEnd(x, y, box, edge = null, rule = 0) {\n if (edge) return [edge === 'left' ? box.left + box.width : box.left, box.top + box.height - rule / 2]\n const tx = Math.min(Math.max(x, box.left), box.left + box.width)\n const ty = Math.min(Math.max(y, box.top), box.top + box.height)\n return Math.hypot(tx - x, ty - y) < 2 ? null : [tx, ty]\n}\n\n/**\n * @typedef {object} LabelBox\n * @property {number} left\n * @property {number} top\n * @property {number} width\n * @property {number} height\n * @property {number} priority higher is kept first\n * @property {'hide' | 'dim' | 'show'} overlap what to do when it loses: hide, dim, or never lose\n * @property {number} depth nearer is kept first among equal priorities\n * @property {boolean} [sticky] it was showing last frame, so it holds its place more firmly\n * @property {boolean} [covered] geometry is in front of it, so it loses to every label\n */\n\n/** @typedef {'show' | 'dim' | 'hide'} LabelState */\n\n/**\n * Which labels to show, dim or hide. 'show' labels go first, then higher priorities, then labels\n * already showing, then nearer ones. A label that runs into one already placed by more than it may\n * (20% of its size, or 50% if it was showing last frame) loses: hidden, or dimmed if its\n * overlap is 'dim'. A covered label always loses, unless its overlap is 'show'. Dimmed labels\n * don't block others. Greedy and stable, so the same view always gives the same answer.\n * @param {LabelBox[]} boxes\n * @returns {LabelState[]} by index\n */\nexport function layoutLabels(boxes) {\n const order = boxes.map((_, i) => i).sort((a, b) => {\n const x = boxes[a], y = boxes[b]\n return (y.overlap === 'show' ? 1 : 0) - (x.overlap === 'show' ? 1 : 0) || y.priority - x.priority ||\n (y.sticky ? 1 : 0) - (x.sticky ? 1 : 0) || x.depth - y.depth || a - b\n })\n /** @type {LabelState[]} */\n const states = new Array(boxes.length).fill('hide')\n /** @type {Map<string, LabelBox[]>} */\n const grid = new Map()\n const cells = (b, fn) => {\n const x0 = Math.floor(b.left / CELL), x1 = Math.floor((b.left + b.width) / CELL)\n const y0 = Math.floor(b.top / CELL), y1 = Math.floor((b.top + b.height) / CELL)\n for (let cx = x0; cx <= x1; cx++) for (let cy = y0; cy <= y1; cy++) fn(`${cx},${cy}`)\n }\n // how far two boxes run into each other, as a share of the smaller size on the axis that parts\n // them soonest - not shared area, which stays small for labels staggered diagonally along an\n // axis even when their text meets\n const shared = (a, b) => {\n const w = Math.min(a.left + a.width, b.left + b.width) - Math.max(a.left, b.left)\n const h = Math.min(a.top + a.height, b.top + b.height) - Math.max(a.top, b.top)\n if (w <= 0 || h <= 0) return 0\n return Math.min(w / Math.max(1, Math.min(a.width, b.width)), h / Math.max(1, Math.min(a.height, b.height)))\n }\n\n for (const i of order) {\n const box = boxes[i]\n if (box.overlap !== 'show') {\n const allowed = box.sticky ? KEEP_OVERLAP : NEW_OVERLAP\n let blocked = !!box.covered\n cells(box, (key) => { if (!blocked) blocked = (grid.get(key) ?? []).some((other) => shared(box, other) > allowed) })\n if (blocked) {\n states[i] = box.overlap === 'dim' ? 'dim' : 'hide'\n continue\n }\n }\n states[i] = 'show'\n cells(box, (key) => {\n let list = grid.get(key)\n if (!list) grid.set(key, list = [])\n list.push(box)\n })\n }\n return states\n}\n","// HTML labels over the canvas: one absolutely positioned element per label, moved each frame to its\n// projected position. Crisp at any pixel ratio, styleable with CSS, and selectable/accessible like\n// any text on the page. Overlapping labels give way by priority (see labelLayout.js).\nimport { alignColumns, layoutLabels, leaderEnd, placeBox, stackColumns } from './labelLayout.js'\n\n/** @import { FrameLabel } from './frame.js' */\n\n/**\n * What happened to this frame's labels.\n * @typedef {object} LabelStats\n * @property {number} total\n * @property {number} shown\n * @property {number} overlapped hidden because a higher-priority label was in the way\n * @property {number} dimmed drawn faint because a higher-priority label or geometry was in front (overlap: 'dim')\n * @property {number} occluded hidden because geometry was in front (overlap: 'hide')\n * @property {number} offscreen behind the camera or outside the view\n * @property {number} zoomedOut hidden because the view isn't zoomed in to their minScale\n */\n\n/** @typedef {{ el: HTMLDivElement, text: string, className: string, width: number, height: number, showing: boolean, leader: SVGGElement | null, color: string, rule: number, label: FrameLabel | null, interactive: boolean }} Entry */\n\n/**\n * What the layer asks of its view: whether a label answers the pointer, and what to do when it does.\n * @typedef {object} LabelPointer\n * @property {(label: FrameLabel) => boolean} interactive\n * @property {(type: 'click' | 'over' | 'out', label: FrameLabel, event: MouseEvent | null) => void} on\n */\n\n/**\n * A leader line as drawn, in CSS pixels over the canvas - for image export.\n * @typedef {{ from: [number, number], to: [number, number], color: string, opacity: number }} Leader\n */\n\nconst SVG = 'http://www.w3.org/2000/svg'\n\n// how faint a covered label is drawn, with overlap: 'dim'\nconst DIM_OPACITY = '0.4'\n\nexport class LabelLayer {\n /** @type {HTMLDivElement | null} */ #root = null\n /** @type {Map<any, Entry>} */ #elements = new Map()\n /** Elements shown in the last frame, for image export. @type {HTMLDivElement[]} */\n shown = []\n /** Leader lines drawn in the last frame, for image export. @type {Leader[]} */\n leaders = []\n /** The lines from labels' points to callouts, under the labels. @type {SVGSVGElement | null} */ #lines = null\n /** Node overlays mounted in the layer. @type {Set<HTMLElement>} */ #overlays = new Set()\n /** @type {WeakMap<Element, Entry>} */ #byElement = new WeakMap()\n /** The label under the pointer, when it answers the pointer. @type {Entry | null} */ #over = null\n\n /** @param {HTMLCanvasElement} canvas @param {LabelPointer} [pointer] */\n constructor(canvas, pointer) {\n this.canvas = canvas\n this.pointer = pointer\n }\n\n /** The layer over the canvas: labels, and overlays such as legends. Made on first use. @returns {HTMLDivElement} */\n get root() {\n return this.#ensureRoot()\n }\n\n /**\n * Position, create, hide and remove label elements for this frame's labels, and mount the\n * overlays of the nodes drawn.\n * @param {(FrameLabel & { occluded?: boolean })[]} labels\n * @param {HTMLElement[]} [overlays]\n * @returns {LabelStats}\n */\n update(labels, overlays = []) {\n /** @type {LabelStats} */\n const stats = { total: labels.length, shown: 0, overlapped: 0, dimmed: 0, occluded: 0, offscreen: 0, zoomedOut: 0 }\n this.shown = []\n this.leaders = []\n if (!labels.length && !this.#elements.size && !overlays.length && !this.#overlays.size && !this.#root) return stats\n const root = this.#ensureRoot()\n this.#mount(root, overlays)\n const rect = this.canvas.getBoundingClientRect()\n this.#place(root)\n\n // 1. elements and text (writes only)\n const seen = new Set()\n /** @type {{ label: FrameLabel & { occluded?: boolean }, entry: Entry }[]} */\n const active = []\n for (const label of labels) {\n seen.add(label.key)\n if (!label.visible) stats.offscreen++\n // details for closer up: until then they take no part, so they can't push other labels out\n else if (label.style.minScale && label.scale * rect.height / 2 < label.style.minScale) stats.zoomedOut++\n else if (label.occluded && label.style.overlap === 'hide') stats.occluded++\n else active.push({ label, entry: this.#entry(label, root) })\n }\n for (const [key, entry] of this.#elements) {\n if (seen.has(key)) continue\n this.#leave(entry)\n entry.el.remove()\n entry.leader?.remove()\n this.#elements.delete(key)\n }\n // 2. measure new or changed labels (one layout pass for all of them)\n for (const { entry } of active) if (entry.width < 0) entry.el.style.display = ''\n for (const { entry } of active) {\n if (entry.width >= 0) continue\n // its own width, not the column's it was given\n entry.el.style.minWidth = ''\n entry.width = entry.el.offsetWidth\n entry.height = entry.el.offsetHeight\n }\n // 3. place, resolve overlaps, and write positions\n const boxes = active.map(({ label, entry }) => {\n const x = (label.ndc[0] * 0.5 + 0.5) * rect.width\n const y = (0.5 - label.ndc[1] * 0.5) * rect.height\n const [left, top] = placeBox(x, y, entry.width, entry.height, label.style.place, label.style.offset, label.style.edge, rect.width)\n // a label showing last frame holds its place more firmly, so labels don't flicker as the view moves\n return { left, top, width: entry.width, height: entry.height, priority: label.style.priority, overlap: label.style.overlap,\n depth: label.depth, sticky: entry.showing, covered: !!label.occluded, x, y, edge: label.style.edge }\n })\n // callouts in a column at an edge are lined up, and spaced out in order, never on top of each other\n alignColumns(boxes)\n stackColumns(boxes, rect.height)\n const states = layoutLabels(boxes)\n // remember what shows this frame, for next frame's stickiness\n for (const entry of this.#elements.values()) entry.showing = false\n const hidden = new Set(this.#elements.values())\n active.forEach(({ label, entry }, i) => {\n const state = states[i]\n entry.showing = state === 'show'\n if (state === 'hide') {\n stats.overlapped++\n return\n }\n hidden.delete(entry)\n // a label of something with click or hover handlers is part of it: it takes the pointer\n entry.label = label\n const interactive = !!this.pointer?.interactive(label)\n if (interactive !== entry.interactive) {\n entry.interactive = interactive\n entry.el.style.pointerEvents = interactive ? 'auto' : ''\n if (interactive) entry.el.dataset.interactive = ''\n else {\n delete entry.el.dataset.interactive\n this.#leave(entry)\n }\n }\n if (state === 'dim') stats.dimmed++\n else stats.shown++\n this.shown.push(entry.el)\n const el = entry.el, box = boxes[i]\n el.style.display = ''\n el.style.opacity = state === 'dim' ? DIM_OPACITY : ''\n // whole pixels keep text crisp - and the box is rounded too, so a leader meets the label where it is drawn\n box.left = Math.round(box.left)\n box.top = Math.round(box.top)\n el.style.transform = `translate(${box.left}px, ${box.top}px)`\n // a column's labels share its width; the right column's text keeps to the edge\n const edge = label.style.edge\n const minWidth = edge && entry.width !== box.width ? `${box.width}px` : '', textAlign = edge === 'right' ? 'right' : ''\n if (el.style.minWidth !== minWidth || el.style.textAlign !== textAlign) Object.assign(el.style, { minWidth, textAlign, boxSizing: minWidth ? 'border-box' : '' })\n // nearer labels stack above further ones, and every dimmed label sits under every shown one\n const near = Math.max(0, Math.round(100000 - label.depth * 100))\n el.style.zIndex = String(state === 'dim' ? Math.min(near, 99999) : 100000 + near)\n if (label.style.leader) this.#leader(entry, box, state === 'dim' ? +DIM_OPACITY : 1)\n else if (entry.leader) {\n entry.leader.remove()\n entry.leader = null\n }\n })\n for (const entry of hidden) {\n this.#leave(entry)\n entry.el.style.display = 'none'\n if (entry.leader) entry.leader.style.display = 'none'\n }\n return stats\n }\n\n /** @param {HTMLDivElement} root @param {HTMLElement[]} overlays */\n #mount(root, overlays) {\n const now = new Set(overlays)\n for (const el of now) {\n if (el.parentElement !== root) root.append(el)\n this.#overlays.add(el)\n }\n // overlays whose node is no longer drawn come off the page\n for (const el of this.#overlays) {\n if (now.has(el)) continue\n el.remove()\n this.#overlays.delete(el)\n }\n }\n\n /**\n * Draw a label's leader: from its point to the nearest point of its box, with a dot on the point.\n * @param {Entry} entry\n * @param {{ left: number, top: number, width: number, height: number, x: number, y: number, edge?: 'left' | 'right' | null }} box\n * @param {number} opacity\n */\n #leader(entry, box, opacity) {\n const { x, y } = box\n // the label's own text colour and underline (read once per look), unless CSS on .phoria-leader says otherwise\n if (!entry.color) {\n const cs = getComputedStyle(entry.el)\n entry.color = cs.color\n entry.rule = cs.borderBottomStyle === 'none' ? 0 : parseFloat(cs.borderBottomWidth) || 0\n }\n const end = leaderEnd(x, y, box, box.edge, entry.rule)\n let g = entry.leader\n if (!g) {\n g = /** @type {SVGGElement} */ (document.createElementNS(SVG, 'g'))\n g.append(document.createElementNS(SVG, 'line'), document.createElementNS(SVG, 'circle'))\n this.#ensureLines().append(g)\n entry.leader = g\n }\n const color = entry.color\n g.setAttribute('class', `phoria-leader${entry.className.slice('phoria-label'.length)}`)\n g.setAttribute('stroke', color)\n g.setAttribute('fill', color)\n g.style.display = ''\n g.style.opacity = String(opacity)\n const [line, dot] = /** @type {[SVGLineElement, SVGCircleElement]} */ (/** @type {unknown} */ ([...g.children]))\n // a point inside its own label needs no line\n line.style.display = end ? '' : 'none'\n if (end) {\n line.setAttribute('x1', String(x))\n line.setAttribute('y1', String(y))\n line.setAttribute('x2', String(end[0]))\n line.setAttribute('y2', String(end[1]))\n line.setAttribute('stroke-width', '1')\n }\n dot.setAttribute('cx', String(x))\n dot.setAttribute('cy', String(y))\n dot.setAttribute('r', '2.5')\n dot.setAttribute('stroke', 'none')\n if (end) this.leaders.push({ from: [x, y], to: end, color, opacity })\n }\n\n /** The SVG the leader lines go in, under every label. @returns {SVGSVGElement} */\n #ensureLines() {\n if (this.#lines) return this.#lines\n const svg = /** @type {SVGSVGElement} */ (document.createElementNS(SVG, 'svg'))\n svg.setAttribute('class', 'phoria-leaders')\n Object.assign(svg.style, { position: 'absolute', left: '0', top: '0', width: '100%', height: '100%', overflow: 'visible', zIndex: '0' })\n this.#ensureRoot().prepend(svg)\n this.#lines = svg\n return svg\n }\n\n /** The pointer is no longer on this label - it went, or stopped answering. @param {Entry} entry */\n #leave(entry) {\n if (this.#over !== entry) return\n this.#over = null\n if (entry.label) this.pointer?.on('out', entry.label, null)\n }\n\n dispose() {\n this.#over = null\n for (const el of this.#overlays) el.remove()\n this.#overlays.clear()\n this.#root?.remove()\n this.#root = null\n this.#lines = null\n this.#elements.clear()\n this.shown = []\n this.leaders = []\n }\n\n /** @param {FrameLabel} label @param {HTMLDivElement} root @returns {Entry} */\n #entry(label, root) {\n let entry = this.#elements.get(label.key)\n if (!entry) {\n const el = document.createElement('div')\n // opacity eases, so dimming and brightening don't flash\n Object.assign(el.style, { position: 'absolute', left: '0', top: '0', willChange: 'transform', transition: 'opacity 0.15s' })\n root.append(el)\n entry = { el, text: '', className: '', width: -1, height: -1, showing: false, leader: null, color: '', rule: 0, label: null, interactive: false }\n this.#elements.set(label.key, entry)\n this.#byElement.set(el, entry)\n }\n const className = `phoria-label${label.style.className ? ` ${label.style.className}` : ''}`\n if (entry.text !== label.text || entry.className !== className) {\n entry.el.textContent = entry.text = label.text\n entry.el.className = entry.className = className\n entry.width = entry.height = -1\n entry.color = ''\n }\n return entry\n }\n\n #ensureRoot() {\n if (this.#root) return this.#root\n // labels keep to one line unless the page's CSS says otherwise: a rule that any other wins over,\n // where an inline style would win over every rule\n if (!document.getElementById('phoria-labels-style')) {\n const style = document.createElement('style')\n style.id = 'phoria-labels-style'\n style.textContent = ':where(.phoria-label) { white-space: nowrap } :where(.phoria-label[data-interactive]) { cursor: pointer }'\n document.head.prepend(style)\n }\n const root = document.createElement('div')\n root.className = 'phoria-labels'\n // its own stacking context, so labels' depth ordering stays below the page's floating UI\n Object.assign(root.style, { position: 'absolute', pointerEvents: 'none', overflow: 'hidden', zIndex: '0', isolation: 'isolate' })\n // beside the canvas, in the same container: when that scrolls or moves, the labels go with it,\n // even while the view is idle and not redrawing\n this.canvas.after(root)\n this.#root = root\n this.#listen(root)\n this.#place(root)\n return root\n }\n\n /** Pass clicks and hovers on labels that answer the pointer to the view. @param {HTMLDivElement} root */\n #listen(root) {\n /** @param {Event} e */\n const entryOf = (e) => {\n const entry = this.#byElement.get(/** @type {Element} */ (e.target))\n return entry?.interactive && entry.label ? entry : null\n }\n root.addEventListener('click', (e) => {\n const entry = entryOf(e)\n if (entry?.label) this.pointer?.on('click', entry.label, e)\n })\n root.addEventListener('pointerover', (e) => {\n const entry = entryOf(e)\n if (!entry?.label || entry === this.#over) return\n this.#over = entry\n this.pointer?.on('over', entry.label, e)\n })\n root.addEventListener('pointerout', (e) => {\n const entry = entryOf(e)\n if (entry && entry === this.#over) this.#leave(entry)\n })\n }\n\n // cover the canvas: same offset parent, so the same offsets; fixed if the canvas is\n /** @param {HTMLDivElement} root */\n #place(root) {\n const c = this.canvas\n root.style.position = getComputedStyle(c).position === 'fixed' ? 'fixed' : 'absolute'\n root.style.left = `${c.offsetLeft + c.clientLeft}px`\n root.style.top = `${c.offsetTop + c.clientTop}px`\n root.style.width = `${c.clientWidth}px`\n root.style.height = `${c.clientHeight}px`\n }\n}\n","import { Vec3 } from './value/Vec3.js'\nimport { checkOneOf, checkOptions, checkRange, describe, fail } from './validate.js'\n\n/** @import { Camera } from './scene/cameras.js' */\n\n/** How far (CSS pixels) a press moves before it is a drag rather than a click - the View's rule too. */\nexport const DRAG_START = 4\n\n/**\n * @typedef {object} OrbitOptions\n * @property {boolean} [enabled] (default true)\n * @property {'orbit' | 'map'} [mode] 'map' makes every drag pan and the view never turn - for plans and maps (default 'orbit')\n * @property {number} [rotateSpeed] radians per pixel of drag (default 0.005)\n * @property {number} [zoomSpeed] fraction of the distance per wheel step (default 0.1)\n * @property {boolean} [zoom] false to leave the wheel scrolling the page (default true)\n * @property {boolean} [zoomToCursor] the wheel zooms towards the point under the pointer (default true)\n * @property {boolean} [pan] right-drag (or two-finger drag) pans (default true)\n * @property {number} [inertia] how much of a fling carries on after release: the fraction of its speed kept\n * every 1/60 s - 0 stops dead, 0.95 glides a long way (default 0.85)\n * @property {boolean | number} [autoRotate] spin around the target; a number is radians per second (default false)\n * @property {number} [minDistance] how close zooming gets to the target; for an orthographic camera, the\n * smallest height of the view (default 0.1)\n * @property {number} [maxDistance] how far zooming goes; for an orthographic camera, the largest height\n * of the view (default Infinity)\n * @property {number} [minPitch] radians below the horizon (default just short of straight down)\n * @property {number} [maxPitch] radians above it (default just short of straight up)\n */\n\nconst OPTIONS = ['enabled', 'mode', 'rotateSpeed', 'zoomSpeed', 'zoom', 'zoomToCursor', 'pan', 'inertia', 'autoRotate',\n 'minDistance', 'maxDistance', 'minPitch', 'maxPitch']\nconst HINTS = {\n enableDamping: \"use 'inertia' (0 to turn it off)\",\n enableRotate: \"use mode: 'map' to make dragging pan instead of turning\",\n rotate: \"use mode: 'map' to make dragging pan instead of turning\",\n enableZoom: \"use 'zoom'\",\n enablePan: \"use 'pan'\",\n screenSpacePanning: 'panning always follows the screen',\n dampingFactor: \"use 'inertia': the fraction of speed kept each 1/60 s (default 0.85)\",\n target: 'set camera.target - the control orbits around it',\n}\nconst LIMIT = Math.PI / 2 - 0.001\n// fastest fling, radians per second\nconst MAX_FLING = 4\n\n/** Check the numbers and modes in orbit options. @param {Record<string, any>} o */\nfunction checkSettings(o) {\n const owner = 'OrbitControl'\n if (o.mode !== undefined) checkOneOf(owner, 'mode', o.mode, ['orbit', 'map'])\n if (o.rotateSpeed !== undefined) checkRange(owner, 'rotateSpeed', o.rotateSpeed, 0)\n if (o.zoomSpeed !== undefined) checkRange(owner, 'zoomSpeed', o.zoomSpeed, 0)\n // the share of speed kept each 1/60 s: 1 would never slow down\n if (o.inertia !== undefined) checkRange(owner, 'inertia', o.inertia, 0, 0.99)\n if (o.autoRotate !== undefined && typeof o.autoRotate !== 'boolean' && (typeof o.autoRotate !== 'number' || !Number.isFinite(o.autoRotate))) {\n fail(owner, `'autoRotate' is true, false or a speed in radians per second, got ${describe(o.autoRotate)}`)\n }\n if (o.minDistance !== undefined) checkRange(owner, 'minDistance', o.minDistance, 0)\n if (o.maxDistance !== undefined) checkRange(owner, 'maxDistance', o.maxDistance, 0, Infinity, { above: true })\n if (o.minPitch !== undefined) checkRange(owner, 'minPitch', o.minPitch, -Math.PI / 2, Math.PI / 2)\n if (o.maxPitch !== undefined) checkRange(owner, 'maxPitch', o.maxPitch, -Math.PI / 2, Math.PI / 2)\n}\n\n/**\n * Mouse and touch camera control: drag (or one finger) orbits the camera around its target,\n * right-drag (or two fingers) pans, the wheel (or a pinch) zooms, towards the pointer. With\n * `mode: 'map'` it is a map control - every drag pans. A drag never counts as a click, so picking\n * on click keeps working. The View creates one with `orbit: true` and calls update()\n * each frame; standalone, call update(dt) yourself for inertia and auto-rotate.\n */\nexport class OrbitControl {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n enabled = true\n /** 'map' makes every drag pan. @type {'orbit' | 'map'} */\n mode = 'orbit'\n rotateSpeed = 0.005\n zoomSpeed = 0.1\n zoom = true\n zoomToCursor = true\n pan = true\n inertia = 0.85\n /** @type {boolean | number} */\n autoRotate = false\n minDistance = 0.1\n maxDistance = Infinity\n minPitch = -LIMIT\n maxPitch = LIMIT\n\n /** @type {Camera} */ camera\n /** @type {HTMLElement} */ element\n /** @type {Map<number, { x: number, y: number }>} */ #pointers = new Map()\n // fling speed in radians per second, measured while dragging\n #velocity = { yaw: 0, pitch: 0 }\n #lastMove = 0\n #panning = false\n #dragged = false\n /** where the press began, to tell a drag from a tap that wobbles @type {{ x: number, y: number }} */\n #pressed = { x: 0, y: 0 }\n #pinchDistance = 0\n /** @type {() => void} */ #removeListeners\n /** @type {(() => void) | null} */ #removePointer = null\n\n /**\n * @param {Camera} camera its target is the pivot; set to the origin if it has none\n * @param {HTMLElement} element usually the canvas\n * @param {OrbitOptions} [options]\n */\n constructor(camera, element, options = {}) {\n checkOptions('OrbitControl', options, OPTIONS, HINTS)\n if (!camera || !('target' in camera)) fail('OrbitControl', 'expects a camera, e.g. new OrbitControl(view.camera, view.canvas)')\n this.camera = camera\n this.element = element\n checkSettings(options)\n Object.assign(this, options)\n // the limits must still make sense with the defaults they're paired with\n if (this.minDistance > this.maxDistance) fail('OrbitControl', `'minDistance' (${this.minDistance}) is more than 'maxDistance' (${this.maxDistance})`)\n if (this.minPitch > this.maxPitch) fail('OrbitControl', `'minPitch' (${this.minPitch}) is more than 'maxPitch' (${this.maxPitch})`)\n camera.target ??= new Vec3()\n\n // touch-action: none stops the browser claiming touch drags for scrolling before we see them\n element.style.touchAction = 'none'\n const down = (e) => this.#down(e), move = (e) => this.#move(e), up = (e) => this.#up(e)\n const wheel = (e) => this.#wheel(e)\n const menu = (e) => { if (this.enabled && this.pan) e.preventDefault() }\n // capture phase, so a drag that ends over the element doesn't also count as a click\n const click = (e) => {\n if (this.#dragged) {\n e.stopImmediatePropagation()\n this.#dragged = false\n }\n }\n element.addEventListener('pointerdown', down)\n element.addEventListener('pointermove', move)\n element.addEventListener('pointerup', up)\n element.addEventListener('pointercancel', up)\n element.addEventListener('wheel', wheel, { passive: false })\n element.addEventListener('contextmenu', menu)\n element.addEventListener('click', click, true)\n this.#pointerHandlers = { down, move, up }\n this.#removePointer = () => {\n element.removeEventListener('pointerdown', down)\n element.removeEventListener('pointermove', move)\n element.removeEventListener('pointerup', up)\n element.removeEventListener('pointercancel', up)\n element.removeEventListener('click', click, true)\n }\n this.#removeListeners = () => {\n this.#removePointer?.()\n element.removeEventListener('wheel', wheel)\n element.removeEventListener('contextmenu', menu)\n }\n }\n\n /** @type {{ down: (e: PointerEvent) => void, move: (e: PointerEvent) => void, up: (e: PointerEvent) => void }} */\n #pointerHandlers\n\n /**\n * @internal Give the pointer to a View, which routes each press - to this orbit, or to dragging a\n * node - and decides what counts as a click. The wheel stays here. Returns what to call for each.\n * @returns {{ down: (e: PointerEvent) => void, move: (e: PointerEvent) => void, up: (e: PointerEvent) => void }}\n */\n handOverPointer() {\n this.#removePointer?.()\n this.#removePointer = null\n return this.#pointerHandlers\n }\n\n /** The target (pivot). @returns {Vec3} */\n get target() {\n return /** @type {Vec3} */ (this.camera.target)\n }\n\n /**\n * Camera position relative to the target: yaw 0 looks from +Z (the front), π/2 from +X (the right);\n * pitch is above the horizon. Setting it moves the camera, within the limits.\n * @returns {{ yaw: number, pitch: number, distance: number }}\n */\n get spherical() {\n const offset = this.camera.position.clone().sub(this.target)\n const distance = offset.len() || this.minDistance\n return { yaw: Math.atan2(offset[0], offset[2]), pitch: Math.asin(Math.max(-1, Math.min(1, offset[1] / distance))), distance }\n }\n\n set spherical({ yaw, pitch, distance }) {\n pitch = Math.min(this.maxPitch, Math.max(this.minPitch, pitch))\n // an orthographic camera's distance doesn't change the picture, so the limits are on its height\n if (!this.#orthographic) distance = Math.min(this.maxDistance, Math.max(this.minDistance, distance))\n const t = this.target\n this.camera.position.set(\n t[0] + distance * Math.cos(pitch) * Math.sin(yaw),\n t[1] + distance * Math.sin(pitch),\n t[2] + distance * Math.cos(pitch) * Math.cos(yaw))\n }\n\n /** Orbit by angles in radians. @param {number} dYaw @param {number} dPitch */\n rotate(dYaw, dPitch) {\n const s = this.spherical\n this.spherical = { yaw: s.yaw + dYaw, pitch: s.pitch + dPitch, distance: s.distance }\n }\n\n /** Scale the distance to the target (0.9 moves closer). Orthographic cameras zoom their view height. @param {number} factor */\n zoomBy(factor) {\n const cam = /** @type {any} */ (this.camera)\n if (this.#orthographic) {\n cam.height = Math.min(this.maxDistance, Math.max(this.minDistance, 1e-4, cam.height * factor))\n return\n }\n const s = this.spherical\n this.spherical = { ...s, distance: s.distance * factor }\n }\n\n /**\n * Zoom by a factor, keeping the point under the pointer still - where the pointer is, in -1..1\n * across the view (x right, y up). The target moves with it, so orbiting then turns about there.\n * @param {number} factor below 1 zooms in\n * @param {number} x @param {number} y\n */\n zoomAt(factor, x, y) {\n const before = this.#halfHeight()\n this.zoomBy(factor)\n // the zoom actually applied, after the distance limits\n const k = 1 - this.#halfHeight() / before\n if (!k) return\n this.camera.updateWorld()\n const m = this.camera.worldMatrix\n const right = new Vec3(m[0], m[1], m[2]).normalize().multiplyScalar(x * before * this.camera.aspect * k)\n const move = new Vec3(m[4], m[5], m[6]).normalize().multiplyScalar(y * before * k).add(right)\n this.camera.position.add(move)\n this.target.add(move)\n }\n\n get #orthographic() {\n return /** @type {any} */ (this.camera).constructor.type === 'orthographic-camera'\n }\n\n // half the view's height at the target, in world units\n #halfHeight() {\n const cam = /** @type {any} */ (this.camera)\n return this.#orthographic ? cam.height / 2 : this.spherical.distance * Math.tan(cam.fov * Math.PI / 360)\n }\n\n /** Move the camera and target together by screen pixels; the scene follows the pointer. @param {number} dx @param {number} dy */\n panBy(dx, dy) {\n this.camera.updateWorld()\n const m = this.camera.worldMatrix\n const right = new Vec3(m[0], m[1], m[2]).normalize()\n const up = new Vec3(m[4], m[5], m[6]).normalize()\n const cam = /** @type {any} */ (this.camera)\n const height = this.element.clientHeight || 1\n const worldPerPixel = this.#orthographic\n ? cam.height / height\n : 2 * this.spherical.distance * Math.tan((cam.fov * Math.PI / 180) / 2) / height\n const move = right.multiplyScalar(-dx * worldPerPixel).add(up.multiplyScalar(dy * worldPerPixel))\n this.camera.position.add(move)\n this.target.add(move)\n }\n\n /**\n * Apply inertia and auto-rotate; the View calls this each frame.\n * @param {number} dt seconds\n * @param {boolean} [still] hold auto-rotation - the View passes its reducedMotion\n */\n update(dt, still = false) {\n if (!this.enabled) return\n if (this.#pointers.size === 0) {\n const v = this.#velocity\n if (Math.abs(v.yaw) > 1e-3 || Math.abs(v.pitch) > 1e-3) {\n this.rotate(v.yaw * dt, v.pitch * dt)\n // the same glide at any frame rate\n const keep = Math.pow(Math.min(0.99, Math.max(0, this.inertia)), dt * 60)\n v.yaw *= keep\n v.pitch *= keep\n }\n if (this.autoRotate && !still) this.rotate(-(this.autoRotate === true ? 0.5 : this.autoRotate) * dt, 0)\n }\n }\n\n /**\n * Let go of the gesture under way - for an app taking the pointer over, such as to drag\n * something across the scene. The camera stays where it is; the next press orbits as usual.\n */\n cancel() {\n this.#pointers.clear()\n this.#pinchDistance = 0\n this.#velocity = { yaw: 0, pitch: 0 }\n this.#dragged = false\n }\n\n dispose() {\n this.#removeListeners()\n this.element.style.touchAction = ''\n }\n\n /** @param {PointerEvent} e */\n #down(e) {\n if (!this.enabled || (e.pointerType === 'mouse' && e.button !== 0 && e.button !== 2)) return\n if (e.button === 2 && !this.pan) return\n // capture is best-effort: it throws for pointers the browser doesn't know, such as scripted events\n try { this.element.setPointerCapture(e.pointerId) } catch { /* drags still work inside the element */ }\n this.#pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })\n this.#pressed = { x: e.clientX, y: e.clientY }\n this.#dragged = false\n this.#velocity = { yaw: 0, pitch: 0 }\n this.#lastMove = performance.now()\n this.#pinchDistance = this.#spread()\n // as a map control, every drag pans\n this.#panning = e.button === 2 || this.mode === 'map'\n if (this.#panning && !this.pan) this.#pointers.delete(e.pointerId)\n }\n\n /** @param {PointerEvent} e */\n #move(e) {\n const last = this.#pointers.get(e.pointerId)\n if (!last || !this.enabled) return\n const dx = e.clientX - last.x, dy = e.clientY - last.y\n last.x = e.clientX\n last.y = e.clientY\n // a tap that moves a pixel or two is still a click - touch and pens nearly always do\n if (!this.#dragged && Math.hypot(e.clientX - this.#pressed.x, e.clientY - this.#pressed.y) >= DRAG_START) this.#dragged = true\n\n if (this.#pointers.size >= 2) {\n // two fingers: pinch zooms, moving together pans (applied per finger, so halve it)\n const spread = this.#spread()\n if (this.zoom && this.#pinchDistance > 0 && spread > 0) this.zoomBy(this.#pinchDistance / spread)\n this.#pinchDistance = spread\n if (this.pan) this.panBy(dx / 2, dy / 2)\n } else if (this.#panning) {\n this.panBy(dx, dy)\n } else {\n // grab the scene: dragging right turns it right, dragging down tips its top towards you\n const dYaw = -dx * this.rotateSpeed, dPitch = dy * this.rotateSpeed\n this.rotate(dYaw, dPitch)\n // speed from the time since the last move, capped so one big jump can't fling it round\n const now = performance.now()\n const elapsed = Math.max(1 / 60, (now - this.#lastMove) / 1000)\n const cap = (w) => Math.max(-MAX_FLING, Math.min(MAX_FLING, w / elapsed))\n this.#velocity = { yaw: cap(dYaw), pitch: cap(dPitch) }\n this.#lastMove = now\n }\n }\n\n /** @param {PointerEvent} e */\n #up(e) {\n this.#pointers.delete(e.pointerId)\n this.#pinchDistance = this.#spread()\n // no fling if the pointer had come to rest before letting go\n if (this.inertia <= 0 || performance.now() - this.#lastMove > 80) this.#velocity = { yaw: 0, pitch: 0 }\n }\n\n /** @param {WheelEvent} e */\n #wheel(e) {\n if (!this.enabled || !this.zoom) return\n e.preventDefault()\n const factor = 1 + Math.sign(e.deltaY) * this.zoomSpeed\n if (!this.zoomToCursor) return this.zoomBy(factor)\n const r = this.element.getBoundingClientRect()\n this.zoomAt(factor, ((e.clientX - r.left) / r.width) * 2 - 1, 1 - ((e.clientY - r.top) / r.height) * 2)\n }\n\n #spread() {\n if (this.#pointers.size < 2) return 0\n const [a, b] = [...this.#pointers.values()]\n return Math.hypot(a.x - b.x, a.y - b.y)\n }\n}\n","import * as mat3 from '../math/mat3.js'\nimport * as mat4 from '../math/mat4.js'\nimport * as quat from '../math/quat.js'\nimport { Mat4 } from '../value/Mat4.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { checkNumber, fail } from '../validate.js'\nimport { NODE_OPTIONS, Node, inParentSpace, setPoint } from './Node.js'\n\n/** @import { NodeOptions } from './Node.js' */\n/** @import { Vec3Input } from '../types.js' */\n\nconst UP = new Float32Array([0, 1, 0])\nconst tmp = new Float32Array(16)\nconst tmp3 = new Float32Array(9)\n\n/**\n * Turn a node to face a target given in its parent's space (the same space as its position).\n * @param {Node} node @param {Vec3} target\n */\nexport function aimAt(node, target) {\n if (node.position.equals(target, 1e-9)) return\n const dir = target.clone().sub(node.position).normalize()\n // world up keeps the picture upright, and turns it smoothly with the view right up to straight up\n // or down - the orbit stops a thousandth of a radian short. Only within a hair of exactly vertical\n // (the 'top' preset's view), where up would no longer say which way the screen faces, is north up\n const up = Math.hypot(dir[0], dir[2]) < 5e-4 ? [0, 0, -1] : UP\n mat4.targetTo(tmp, node.position, target, up)\n const q = quat.normalize(new Float32Array(4), quat.fromMat3(new Float32Array(4), mat3.fromMat4(tmp3, tmp)))\n node.quaternion.copy(q)\n}\n\n/**\n * @typedef {NodeOptions & { near?: number, far?: number, target?: Vec3Input }} CameraOptions\n */\n\nconst CAMERA_OPTIONS = [...NODE_OPTIONS, 'near', 'far', 'target', 'aspect']\nconst CAMERA_HINTS = {\n lookAt: \"use target: [x, y, z], or call camera.lookAt(...) after creating it\",\n zoom: \"move the camera, or change 'fov' (perspective) or 'height' (orthographic)\",\n}\n\n/** Base for cameras. Cameras look down their local -Z axis. */\nexport class Camera extends Node {\n static OPTIONS = CAMERA_OPTIONS\n static HINTS = CAMERA_HINTS\n\n near = 0.1\n far = 1000\n /** Width / height - set by the View to match the canvas. */\n aspect = 1\n /** @type {Vec3 | null} */ #target = null\n\n /** @param {CameraOptions & { aspect?: number }} [options] */\n constructor(options = {}) {\n super(options)\n const owner = this.constructor.name\n if (options.near !== undefined) this.near = checkNumber(owner, 'near', options.near)\n if (options.far !== undefined) this.far = checkNumber(owner, 'far', options.far)\n if (options.aspect !== undefined) this.aspect = checkNumber(owner, 'aspect', options.aspect)\n if (!(this.near > 0) || !(this.far > this.near)) fail(owner, `needs 0 < near < far, got near ${this.near} and far ${this.far}`)\n if (options.target !== undefined) this.target = Vec3.fromInput(options.target, owner)\n }\n\n /**\n * When set, the camera turns to face it every frame. In the same space as `position` (world\n * space for a camera that isn't parented). Orbit controls use it as their pivot. Assigning copies\n * the point in: camera.target = [0, 1, 0]; null lets the camera turn freely.\n * @returns {Vec3 | null}\n */\n get target() { return this.#target }\n /** @param {import('../types.js').Vec3Input | null} v */\n set target(v) { this.#target = setPoint(this.#target, v, this.constructor.name) }\n\n updateMatrix() {\n if (this.target) aimAt(this, this.target)\n return super.updateMatrix()\n }\n\n /**\n * Look at a world position or node. A camera with a target keeps aiming at it - every View camera\n * has one, and its orbit control turns about it - so the target moves there instead.\n * @param {import('../types.js').Vec3Input | Node} target @param {import('../types.js').Vec3Input} [up]\n * @returns {this}\n */\n lookAt(target, up) {\n if (!this.target) return super.lookAt(target, up)\n this.target.copy(inParentSpace(this, target))\n return this\n }\n\n /** The projection matrix for the current settings. @returns {Mat4} */\n get projectionMatrix() {\n return new Mat4()\n }\n\n /** The inverse of the world matrix, as of the last update. @returns {Mat4} */\n get viewMatrix() {\n return this.worldMatrix.clone().invert()\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), near: this.near, far: this.far, aspect: this.aspect, ...(this.target ? { target: this.target.toArray() } : {}) }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = {}\n if (this.near !== 0.1) json.near = this.near\n if (this.far !== 1000) json.far = this.far\n if (this.target) json.target = this.target.toArray()\n return json\n }\n}\n\n/** A camera with perspective: things further away look smaller. */\nexport class PerspectiveCamera extends Camera {\n static type = 'perspective-camera'\n static get OPTIONS() { return [...CAMERA_OPTIONS, 'fov'] }\n\n /** Vertical field of view in degrees. */\n fov = 50\n\n /** @param {CameraOptions & { fov?: number }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.fov !== undefined) {\n this.fov = checkNumber('PerspectiveCamera', 'fov', options.fov)\n if (this.fov <= 0 || this.fov >= 180) fail('PerspectiveCamera', `'fov' is the vertical angle in degrees, 0-180 exclusive, got ${this.fov}`)\n }\n }\n\n get projectionMatrix() {\n return mat4.perspective(new Mat4(), this.fov * Math.PI / 180, this.aspect, this.near, this.far)\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), fov: this.fov }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.fov !== 50 ? { fov: this.fov } : {}) }\n }\n}\n\n/** A camera without perspective: sizes don't change with distance. Isometric views, 2D-ish data viz. */\nexport class OrthographicCamera extends Camera {\n static type = 'orthographic-camera'\n static get OPTIONS() { return [...CAMERA_OPTIONS, 'height'] }\n\n /** Height of the view in world units; the width follows the aspect. */\n height = 10\n\n /** @param {CameraOptions & { height?: number }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.height !== undefined) this.height = checkNumber('OrthographicCamera', 'height', options.height)\n }\n\n get projectionMatrix() {\n const h = this.height / 2, w = h * this.aspect\n return mat4.ortho(new Mat4(), -w, w, -h, h, this.near, this.far)\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), height: this.height }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.height !== 10 ? { height: this.height } : {}) }\n }\n}\n","// Named camera setups for the common business views: an isometric diorama, a plan from above, a\n// front or side elevation, or a plain perspective. The View fits a preset camera to the scene.\nimport { OrthographicCamera, PerspectiveCamera } from './scene/cameras.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { fail, didYouMean } from './validate.js'\n\n/** @import { Box3 } from './value/Box3.js' */\n\n/** @typedef {'perspective' | 'isometric' | 'top' | 'front' | 'side'} CameraPreset */\n\n/** Direction from the target to the camera, per preset. */\nconst DIRECTIONS = {\n perspective: [0.6, 0.45, 1],\n isometric: [1, 1, 1],\n top: [0, 1, 0],\n front: [0, 0, 1],\n side: [1, 0, 0],\n}\nexport const CAMERA_PRESETS = /** @type {CameraPreset[]} */ (Object.keys(DIRECTIONS))\n\n// words people use for these views\nconst ALIASES = {\n ortho: 'isometric', orthographic: 'isometric', iso: 'isometric', plan: 'top', overhead: 'top', above: 'top',\n map: 'top', elevation: 'front', left: 'side', right: 'side', persp: 'perspective', '3d': 'perspective',\n}\n\n/**\n * A camera for a preset, looking at `target` from `distance` away. Every preset but 'perspective'\n * is orthographic, so sizes don't shrink with distance - the norm for diagrams and plans.\n * @param {CameraPreset} name\n * @param {{ target?: ArrayLike<number>, distance?: number }} [from]\n * @returns {PerspectiveCamera | OrthographicCamera}\n */\nexport function cameraPreset(name, { target = [0, 0, 0], distance = 10 } = {}) {\n const direction = presetDirection(name)\n const position = new Vec3(target[0], target[1], target[2]).add(direction.multiplyScalar(distance))\n return name === 'perspective'\n ? new PerspectiveCamera({ fov: 45, position, target: [target[0], target[1], target[2]] })\n : new OrthographicCamera({ height: distance, position, target: [target[0], target[1], target[2]], far: Math.max(1000, distance * 20) })\n}\n\n/**\n * The unit direction from the target to a preset's camera.\n * @param {CameraPreset} name\n * @returns {Vec3}\n */\nexport function presetDirection(name) {\n if (!(name in DIRECTIONS)) {\n const alias = ALIASES[String(name).toLowerCase()]\n fail('View', `camera '${name}' is not a preset - ${alias ? `use '${alias}'` : `expected one of ${CAMERA_PRESETS.map((p) => `'${p}'`).join(', ')}${didYouMean(String(name), CAMERA_PRESETS)}`}`)\n }\n return new Vec3(...DIRECTIONS[name]).normalize()\n}\n\n// where a perspective picture's middle sits, below the view's middle (in half-heights of the view):\n// a little low, so things standing on a floor look grounded rather than hung from the top edge\nconst LOW = 0.12\n\n/**\n * How to fit a set of points in view from `direction`: where to look (the centre) and the distance\n * for a perspective camera (give `fov`), or the view height for an orthographic one. Every point\n * lands inside the view with `padding` to spare. Fitting the corners of each thing drawn, rather\n * than one box round them all, keeps a picture from sitting small in the box's empty corners. An\n * orthographic picture is centred; a perspective one - whose near side looks bigger - is moved\n * until it sits just below the middle, filling as much of the view as that allows.\n * @param {ArrayLike<number>[]} points world positions, at least one\n * @param {ArrayLike<number>} direction a unit vector from the points towards the camera\n * @param {{ aspect: number, fov?: number, padding?: number }} view fov in degrees, vertical (perspective; leave it out for\n * orthographic); padding is the margin as a fraction of the size, as for view.frame()\n * @returns {{ center: Vec3, size: number }}\n */\nexport function fitPoints(points, direction, { aspect, fov, padding = 0 }) {\n const scale = 1 + padding, wide = aspect > 0 ? aspect : 1\n const ahead = new Vec3(-direction[0], -direction[1], -direction[2])\n const right = ahead.clone().cross(Math.abs(ahead[1]) > 0.9999 ? [0, 0, -1] : [0, 1, 0]).normalize()\n const up = right.clone().cross(ahead)\n const axes = [right, up, ahead]\n // the points in the camera's axes, and the middle of their spread\n const local = points.map((p) => axes.map((a) => p[0] * a[0] + p[1] * a[1] + p[2] * a[2]))\n const lo = [0, 1, 2].map((k) => Math.min(...local.map((q) => q[k]))), hi = [0, 1, 2].map((k) => Math.max(...local.map((q) => q[k])))\n const mid = [0, 1, 2].map((k) => (lo[k] + hi[k]) / 2)\n const world = (k) => right[k] * mid[0] + up[k] * mid[1] + ahead[k] * mid[2]\n const centerOf = () => new Vec3(world(0), world(1), world(2))\n if (fov === undefined) {\n const half = Math.max((hi[1] - lo[1]) / 2, (hi[0] - lo[0]) / 2 / wide) * scale\n return { center: centerOf(), size: Math.max(half * 2, 1e-3) }\n }\n const tanV = Math.tan(fov * Math.PI / 360), tanH = tanV * wide\n const near = Math.max(...[0, 1, 2].map((k) => hi[k] - lo[k]), 1e-3) * 0.05\n // back far enough that every point, about the centre, is inside the view\n const distance = () => Math.max(1e-3, ...local.map((q) => {\n const x = Math.abs(q[0] - mid[0]) * scale, y = Math.abs(q[1] - mid[1]) * scale, z = q[2] - mid[2]\n return Math.max(x / tanH - z, y / tanV - z, near - z)\n }))\n let d = distance()\n for (let i = 0; i < 8; i++) {\n // where the points land, from -1 to 1 across the view: move the centre until their middle is\n // across the middle of the view, and just below it\n let u0 = Infinity, u1 = -Infinity, v0 = Infinity, v1 = -Infinity\n for (const q of local) {\n const depth = d + q[2] - mid[2], u = (q[0] - mid[0]) / depth / tanH, v = (q[1] - mid[1]) / depth / tanV\n u0 = Math.min(u0, u); u1 = Math.max(u1, u); v0 = Math.min(v0, v); v1 = Math.max(v1, v)\n }\n const du = (u0 + u1) / 2, dv = (v0 + v1) / 2 + LOW\n if (Math.abs(du) < 1e-4 && Math.abs(dv) < 1e-4) break\n mid[0] += du * tanH * d\n mid[1] += dv * tanV * d\n d = distance()\n }\n return { center: centerOf(), size: d }\n}\n\n/** @typedef {'height' | 'width' | 'both'} FramingKeep */\n\n/**\n * How much bigger (or smaller) the view must be to keep a camera's framing when the canvas's shape\n * changes from `designed` (the aspect the framing was set for) to `aspect`. 'height' keeps the\n * framed height (the width varies - the default for any camera); 'width' keeps the framed width;\n * 'both' keeps everything framed in view, widening for narrower canvases and keeping the height for\n * wider ones.\n * @param {FramingKeep} keep @param {number} designed @param {number} aspect\n * @returns {number} the factor for an orthographic camera's height, or a perspective camera's distance\n */\nexport function framingScale(keep, designed, aspect) {\n if (keep === 'height' || !(aspect > 0) || !(designed > 0)) return 1\n const ratio = designed / aspect\n return keep === 'width' ? ratio : Math.max(1, ratio)\n}\n","// Easing: how progress runs from 0 to 1 - steady, or easing in and out. One table for timelines\n// (phoria2/motion) and charts' transitions, so both take the same names.\n\n/** @typedef {'linear' | 'in' | 'out' | 'inOut'} EaseName */\n\n/** @type {Record<EaseName, (t: number) => number>} */\nexport const EASES = {\n linear: (t) => t,\n in: (t) => t * t * t,\n out: (t) => 1 - (1 - t) ** 3,\n inOut: (t) => (t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2),\n}\n","import { Vec3 } from './Vec3.js'\n\nconst edge1 = new Vec3(), edge2 = new Vec3(), pvec = new Vec3(), tvec = new Vec3(), qvec = new Vec3()\n\n/** A ray: an origin and a (normalised) direction. */\nexport class Ray {\n origin = new Vec3()\n direction = new Vec3(0, 0, -1)\n\n /** @param {ArrayLike<number>} [origin] @param {ArrayLike<number>} [direction] */\n constructor(origin, direction) {\n if (origin) this.origin.set(origin[0], origin[1], origin[2])\n if (direction) this.direction.set(direction[0], direction[1], direction[2]).normalize()\n }\n\n /** The point at distance t along the ray. @param {number} t @param {Vec3} [out] @returns {Vec3} */\n at(t, out = new Vec3()) {\n return out.copy(this.direction).multiplyScalar(t).add(this.origin)\n }\n\n /** @returns {Ray} */\n clone() {\n return new Ray(this.origin, this.direction)\n }\n\n /** Transform by a 4x4 (direction ignores translation, and is re-normalised). @param {ArrayLike<number>} m @returns {this} */\n applyMatrix4(m) {\n const end = this.at(1)\n this.origin.applyMatrix4(/** @type {Float32Array} */ (m))\n end.applyMatrix4(/** @type {Float32Array} */ (m))\n this.direction.copy(end).sub(this.origin).normalize()\n return this\n }\n\n /** Distance to where the ray enters a sphere, or null if it misses (or the sphere is behind). @param {ArrayLike<number>} center @param {number} radius @returns {number | null} */\n intersectSphere(center, radius) {\n tvec.set(center[0], center[1], center[2]).sub(this.origin)\n const along = tvec.dot(this.direction)\n const d2 = tvec.dot(tvec) - along * along\n const r2 = radius * radius\n if (d2 > r2) return null\n const half = Math.sqrt(r2 - d2)\n const t0 = along - half, t1 = along + half\n if (t1 < 0) return null\n return t0 < 0 ? t1 : t0\n }\n\n /**\n * Distance to where the ray meets a plane - given by its normal and a point on it - or null when\n * it runs along the plane or the plane is behind it. For dragging things across a floor:\n * ray.at(ray.intersectPlane([0, 1, 0], [0, 0, 0])).\n * @param {ArrayLike<number>} normal @param {ArrayLike<number>} point\n * @returns {number | null}\n */\n intersectPlane(normal, point) {\n const across = normal[0] * this.direction[0] + normal[1] * this.direction[1] + normal[2] * this.direction[2]\n if (Math.abs(across) < 1e-9) return null\n const t = (normal[0] * (point[0] - this.origin[0]) + normal[1] * (point[1] - this.origin[1]) + normal[2] * (point[2] - this.origin[2])) / across\n return t >= 0 ? t : null\n }\n\n /**\n * Möller-Trumbore ray/triangle test: the distance along the ray and barycentric (u, v), or null.\n * Triangles facing away (clockwise from the ray's side) are skipped when cullBack is set.\n * @param {ArrayLike<number>} a @param {ArrayLike<number>} b @param {ArrayLike<number>} c\n * @param {boolean} cullBack\n * @returns {{ t: number, u: number, v: number } | null}\n */\n intersectTriangle(a, b, c, cullBack) {\n edge1.set(b[0] - a[0], b[1] - a[1], b[2] - a[2])\n edge2.set(c[0] - a[0], c[1] - a[1], c[2] - a[2])\n pvec.copy(this.direction).cross(edge2)\n const det = edge1.dot(pvec)\n if (cullBack ? det < 1e-10 : Math.abs(det) < 1e-10) return null\n const inv = 1 / det\n tvec.set(this.origin[0] - a[0], this.origin[1] - a[1], this.origin[2] - a[2])\n const u = tvec.dot(pvec) * inv\n if (u < 0 || u > 1) return null\n qvec.copy(tvec).cross(edge1)\n const v = this.direction.dot(qvec) * inv\n if (v < 0 || u + v > 1) return null\n const t = edge2.dot(qvec) * inv\n return t >= 0 ? { t, u, v } : null\n }\n\n /** Squared distance from the ray to a point, and how far along the ray the closest approach is. @param {ArrayLike<number>} p @returns {{ distanceSq: number, t: number }} */\n distanceSqToPoint(p) {\n tvec.set(p[0] - this.origin[0], p[1] - this.origin[1], p[2] - this.origin[2])\n const t = Math.max(0, tvec.dot(this.direction))\n const closest = this.at(t, qvec)\n return { distanceSq: (p[0] - closest[0]) ** 2 + (p[1] - closest[1]) ** 2 + (p[2] - closest[2]) ** 2, t }\n }\n\n /**\n * Squared distance between the ray and a line segment, with the closest points' parameters.\n * @param {ArrayLike<number>} v0 @param {ArrayLike<number>} v1\n * @returns {{ distanceSq: number, t: number, s: number }} t along the ray, s 0-1 along the segment\n */\n distanceSqToSegment(v0, v1) {\n // closest points between two lines, then clamped to the ray (t >= 0) and segment (0 <= s <= 1)\n const d = this.direction\n const ex = v1[0] - v0[0], ey = v1[1] - v0[1], ez = v1[2] - v0[2]\n const wx = this.origin[0] - v0[0], wy = this.origin[1] - v0[1], wz = this.origin[2] - v0[2]\n const a = 1, b = d[0] * ex + d[1] * ey + d[2] * ez, c = ex * ex + ey * ey + ez * ez\n const dd = d[0] * wx + d[1] * wy + d[2] * wz, e = ex * wx + ey * wy + ez * wz\n const denom = a * c - b * b\n let s = denom > 1e-12 ? (a * e - b * dd) / denom : 0\n s = Math.min(1, Math.max(0, s))\n let t = b * s - dd\n // nearest behind the ray's start: from the start, the nearest point of the segment is another one\n if (t < 0) {\n t = 0\n s = c > 1e-12 ? Math.min(1, Math.max(0, e / c)) : 0\n }\n const px = this.origin[0] + d[0] * t - (v0[0] + ex * s)\n const py = this.origin[1] + d[1] * t - (v0[1] + ey * s)\n const pz = this.origin[2] + d[2] * t - (v0[2] + ez * s)\n return { distanceSq: px * px + py * py + pz * pz, t, s }\n }\n}\n","// A bounding volume hierarchy over a geometry's triangles, so a ray tests a few dozen boxes and a\n// handful of triangles rather than every triangle - picking, label occlusion and the exact step of\n// GPU picking stay quick on models of hundreds of thousands of triangles. Built the first time a\n// ray needs it, and again only when the geometry changes (needsUpdate()).\n\n/** @import { Geometry } from './Geometry.js' */\n\n// triangles in a leaf, at most\nconst LEAF = 8\n// below this, testing every triangle is as quick as building and walking a tree\nexport const BVH_MIN_TRIANGLES = 128\n\n/**\n * @typedef {object} BVH\n * @property {Float32Array} boxes min xyz, max xyz per node\n * @property {Int32Array} nodes per node: the first child (inner) or first triangle slot (leaf),\n * and the triangle count (0 for an inner node, whose children are at first and first + 1)\n * @property {Uint32Array} order triangle indices, grouped by leaf\n */\n\n/** @type {WeakMap<Geometry, { version: number, count: number, bvh: BVH }>} */\nconst cache = new WeakMap()\n\n/**\n * The geometry's BVH over its first `count` triangles, built now if it hasn't been or the geometry\n * has changed since.\n * @param {Geometry} g @param {number} count triangles\n * @returns {BVH}\n */\nexport function bvhOf(g, count) {\n const hit = cache.get(g)\n if (hit && hit.version === g.version && hit.count === count) return hit.bvh\n const bvh = build(g, count)\n cache.set(g, { version: g.version, count, bvh })\n return bvh\n}\n\n/** @param {Geometry} g @param {number} count @returns {BVH} */\nfunction build(g, count) {\n const p = g.positions, idx = g.indices\n const corner = (f, k) => (idx ? idx[f * 3 + k] : f * 3 + k) * 3\n // each triangle's box and centre\n const tri = new Float32Array(count * 9)\n for (let f = 0; f < count; f++) {\n const a = corner(f, 0), b = corner(f, 1), c = corner(f, 2)\n for (let k = 0; k < 3; k++) {\n const lo = Math.min(p[a + k], p[b + k], p[c + k]), hi = Math.max(p[a + k], p[b + k], p[c + k])\n tri[f * 9 + k] = lo\n tri[f * 9 + 3 + k] = hi\n tri[f * 9 + 6 + k] = (lo + hi) / 2\n }\n }\n const order = new Uint32Array(count)\n for (let f = 0; f < count; f++) order[f] = f\n const maxNodes = Math.max(1, 2 * Math.ceil(count / LEAF) * 2)\n let boxes = new Float32Array(maxNodes * 6), nodes = new Int32Array(maxNodes * 2), used = 0\n const grow = () => {\n const b = new Float32Array(boxes.length * 2), n = new Int32Array(nodes.length * 2)\n b.set(boxes); n.set(nodes)\n boxes = b; nodes = n\n }\n const alloc = () => {\n if ((used + 1) * 2 > nodes.length) grow()\n return used++\n }\n // split [start, end) of order into the node at `at`, longest axis of the centres, at the median\n const stack = [[alloc(), 0, count]]\n while (stack.length) {\n const [at, start, end] = /** @type {number[]} */ (stack.pop())\n let x0 = Infinity, y0 = Infinity, z0 = Infinity, x1 = -Infinity, y1 = -Infinity, z1 = -Infinity\n let cx0 = Infinity, cy0 = Infinity, cz0 = Infinity, cx1 = -Infinity, cy1 = -Infinity, cz1 = -Infinity\n for (let i = start; i < end; i++) {\n const t = order[i] * 9\n x0 = Math.min(x0, tri[t]); y0 = Math.min(y0, tri[t + 1]); z0 = Math.min(z0, tri[t + 2])\n x1 = Math.max(x1, tri[t + 3]); y1 = Math.max(y1, tri[t + 4]); z1 = Math.max(z1, tri[t + 5])\n cx0 = Math.min(cx0, tri[t + 6]); cy0 = Math.min(cy0, tri[t + 7]); cz0 = Math.min(cz0, tri[t + 8])\n cx1 = Math.max(cx1, tri[t + 6]); cy1 = Math.max(cy1, tri[t + 7]); cz1 = Math.max(cz1, tri[t + 8])\n }\n boxes.set([x0, y0, z0, x1, y1, z1], at * 6)\n const sx = cx1 - cx0, sy = cy1 - cy0, sz = cz1 - cz0\n if (end - start <= LEAF || Math.max(sx, sy, sz) <= 0) {\n nodes[at * 2] = start\n nodes[at * 2 + 1] = end - start\n continue\n }\n const axis = sx >= sy && sx >= sz ? 6 : sy >= sz ? 7 : 8\n const mid = (start + end) >> 1\n partition(order, tri, axis, start, end, mid)\n const left = alloc()\n alloc()\n nodes[at * 2] = left\n nodes[at * 2 + 1] = 0\n stack.push([left, start, mid], [left + 1, mid, end])\n }\n return { boxes: boxes.slice(0, used * 6), nodes: nodes.slice(0, used * 2), order }\n}\n\n/**\n * Put the k-th smallest (by centre on `axis`) at k, smaller before it and larger after - quickselect.\n * @param {Uint32Array} order @param {Float32Array} tri @param {number} axis @param {number} lo @param {number} hi @param {number} k\n */\nfunction partition(order, tri, axis, lo, hi, k) {\n let l = lo, r = hi - 1\n while (l < r) {\n const pivot = tri[order[(l + r) >> 1] * 9 + axis]\n let i = l, j = r\n while (i <= j) {\n while (tri[order[i] * 9 + axis] < pivot) i++\n while (tri[order[j] * 9 + axis] > pivot) j--\n if (i <= j) {\n const s = order[i]; order[i] = order[j]; order[j] = s\n i++; j--\n }\n }\n if (k <= j) r = j\n else if (k >= i) l = i\n else break\n }\n}\n\n/**\n * Walk the tree along a ray, nearest boxes first, calling `test(triangle)` for each triangle in a\n * leaf the ray reaches. `test` returns the distance of the nearest hit so far (Infinity for none),\n * and boxes further than that are skipped.\n * @param {BVH} bvh @param {ArrayLike<number>} o ray origin @param {ArrayLike<number>} d ray direction\n * @param {(triangle: number) => number} test\n */\nexport function walk(bvh, o, d, test) {\n const { boxes, nodes, order } = bvh\n const ix = 1 / d[0], iy = 1 / d[1], iz = 1 / d[2]\n // where the ray enters a node's box, or Infinity if it misses\n const enter = (n) => {\n const b = n * 6\n let t0 = (boxes[b] - o[0]) * ix, t1 = (boxes[b + 3] - o[0]) * ix\n let lo = Math.min(t0, t1), hi = Math.max(t0, t1)\n t0 = (boxes[b + 1] - o[1]) * iy; t1 = (boxes[b + 4] - o[1]) * iy\n lo = Math.max(lo, Math.min(t0, t1)); hi = Math.min(hi, Math.max(t0, t1))\n t0 = (boxes[b + 2] - o[2]) * iz; t1 = (boxes[b + 5] - o[2]) * iz\n lo = Math.max(lo, Math.min(t0, t1)); hi = Math.min(hi, Math.max(t0, t1))\n // NaN from a ray along a face counts as a hit - better a test too many than a miss\n return hi >= Math.max(lo, 0) || Number.isNaN(lo) || Number.isNaN(hi) ? Math.max(lo, 0) || 0 : Infinity\n }\n let best = Infinity\n // a box is worth opening if the ray enters it at all (a miss is Infinity - never worth it, even\n // before anything has been hit) and no further away than the nearest hit so far\n const worth = (t) => t !== Infinity && t <= best\n const root = enter(0)\n if (root === Infinity) return\n const stack = [0], at = [root]\n while (stack.length) {\n const n = /** @type {number} */ (stack.pop()), t = /** @type {number} */ (at.pop())\n if (t > best) continue\n const first = nodes[n * 2], count = nodes[n * 2 + 1]\n if (count) {\n for (let i = first; i < first + count; i++) best = Math.min(best, test(order[i]))\n continue\n }\n const a = enter(first), b = enter(first + 1)\n // the nearer child last, so it comes off the stack first\n if (a <= b) {\n if (worth(b)) { stack.push(first + 1); at.push(b) }\n if (worth(a)) { stack.push(first); at.push(a) }\n } else {\n if (worth(a)) { stack.push(first); at.push(a) }\n if (worth(b)) { stack.push(first + 1); at.push(b) }\n }\n }\n}\n","import * as mat3 from './math/mat3.js'\nimport * as mat4 from './math/mat4.js'\nimport { Ray } from './value/Ray.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { clipOwner, worldPlane } from './clip.js'\nimport { BVH_MIN_TRIANGLES, bvhOf, walk } from './geometry/bvh.js'\n\n/** @import { Camera } from './scene/cameras.js' */\n/** @import { Node } from './scene/Node.js' */\n/** @import { InstancedMesh, Lines, Mesh, Points } from './scene/drawables.js' */\n\n/** The section plane cutting what is being tested: world plane, and whether its cut faces are filled. @typedef {{ plane: Float32Array, cap: boolean }} Cut */\n/** @internal A surface ready for many rays: a mesh or one instance, with its world matrix and bounding sphere. @typedef {{ node: any, world: Float32Array, instance: number | null, cut: Cut | null, x: number, y: number, z: number, radius: number }} Solid */\n\n// Nodes are told apart by markers (drawMode, instanceMatrices) rather than instanceof, so picking\n// doesn't pull every node class into an app's bundle.\n\n/**\n * A pick result.\n * @typedef {object} Hit\n * @property {Node} node what was hit\n * @property {Vec3} point world position of the hit\n * @property {number} distance from the ray origin, world units\n * @property {Vec3 | null} normal world space face normal (meshes)\n * @property {number | null} face triangle index (meshes), vertex index (points), segment index (lines)\n * @property {number | null} instance instance index (InstancedMesh)\n * @property {[number, number] | null} uv texture coordinate at the hit (meshes with uvs)\n * @property {any} datum the node's data for what was hit: its row for an instance or point, or the\n * node's own data (null when it has none)\n */\n\nconst inverse = new Float32Array(16)\nconst instanceWorld = new Float32Array(16)\nconst a = new Vec3(), b = new Vec3(), c = new Vec3()\nconst localPlane = new Float32Array(4)\n\n/** The cut a node's nearest clip makes, or null. @param {Node | null} owner @returns {Cut | null} */\nconst cutBy = (owner) => (owner?.clip ? { plane: worldPlane(owner), cap: !!owner.clip.cap } : null)\n\n/**\n * Finds what a ray hits, on the CPU - no GPU read-back, so it also works in tests. Meshes are\n * tested against their triangles after a bounding sphere check; points and lines within a\n * tolerance in world units.\n */\nexport class Raycaster {\n ray = new Ray()\n near = 0\n far = Infinity\n /** How close (world units) a ray must pass to a point or line to hit it. */\n threshold = 0.1\n /** The camera it was aimed from (setFromCamera): what showFrom hides from it can't be hit. @type {Camera | null} */\n camera = null\n\n /**\n * Aim the ray through a position on screen.\n * @param {ArrayLike<number>} ndc [x, y] in normalised device coordinates, -1 to 1 (y up)\n * @param {Camera} camera\n * @returns {this}\n */\n setFromCamera(ndc, camera) {\n camera.updateWorld()\n this.camera = camera\n if (/** @type {any} */ (camera.constructor).type === 'orthographic-camera') {\n // parallel rays: from the near plane, straight through to the far one\n const inv = mat4.invert(new Float32Array(16), mat4.multiply(new Float32Array(16), camera.projectionMatrix, camera.viewMatrix))\n if (!inv) return this\n const near = new Vec3(ndc[0], ndc[1], -1).applyMatrix4(inv)\n this.ray.origin.copy(near)\n this.ray.direction.copy(new Vec3(ndc[0], ndc[1], 1).applyMatrix4(inv)).sub(near).normalize()\n return this\n }\n // from the camera along the pixel's line of sight, worked out in the camera's own space and\n // turned to the world - exact whatever the near and far planes (far: Infinity included)\n const p = camera.projectionMatrix, m = camera.worldMatrix\n const x = (ndc[0] + p[8]) / p[0], y = (ndc[1] + p[9]) / p[5]\n this.ray.origin.copy(camera.worldPosition)\n this.ray.direction.set(m[0] * x + m[4] * y - m[8], m[1] * x + m[5] * y - m[9], m[2] * x + m[6] * y - m[10]).normalize()\n return this\n }\n\n /**\n * Everything the ray hits, nearest first. Invisible and unpickable nodes (and their children)\n * are skipped, and so are those showFrom hides from the camera it was aimed from - only what is\n * drawn is hit. World matrices are brought up to date first.\n * @param {Node | Node[]} targets\n * @returns {Hit[]}\n */\n intersect(targets) {\n /** @type {Hit[]} */\n const hits = []\n for (const target of [targets].flat()) {\n target.updateWorld()\n // a clip above the target cuts it too\n this.#visit(target, hits, cutBy(clipOwner(target.parent)))\n }\n return hits.filter((h) => h.distance >= this.near && h.distance <= this.far).sort((x, y) => x.distance - y.distance)\n }\n\n /** @internal\n * The surfaces among what a frame drew that the ray meets, nearest first - its triangles, instanced\n * or not, cut as they were drawn. For questions about the picture just drawn, such as whether a\n * label is hidden behind something: what was drawn is the answer, pickable or not.\n * @param {import('./frame.js').DrawItem[]} items\n * @returns {Hit[]}\n */\n intersectDrawn(items) {\n /** @type {Hit[]} */\n const hits = []\n for (const item of items) {\n const n = /** @type {any} */ (item.node)\n if (n.drawMode !== 'triangles') continue\n const cut = item.clip ? { plane: item.clip.plane, cap: !!item.clip.cap } : null\n if (item.instances) {\n for (let i = 0; i < item.instances.count; i++) {\n mat4.multiply(instanceWorld, item.worldMatrix, item.instances.instanceMatrices.subarray(i * 16, i * 16 + 16))\n this.#mesh(n, instanceWorld, i, hits, cut)\n }\n } else this.#mesh(n, item.worldMatrix, null, hits, cut)\n }\n return hits.filter((h) => h.distance >= this.near && h.distance <= this.far).sort((x, y) => x.distance - y.distance)\n }\n\n /** @internal\n * The solid surfaces of a frame's draw list, ready for many rays: each mesh and each instance with its\n * world matrix and bounding sphere worked out once, rather than once per ray - for label occlusion,\n * which casts a ray per label.\n * @param {{ node: Node, worldMatrix: Float32Array, instances: { count: number, instanceMatrices: Float32Array } | null, clip: { plane: Float32Array, cap: unknown } | null }[]} items\n * @returns {Solid[]}\n */\n static solids(items) {\n /** @type {Solid[]} */\n const out = []\n for (const item of items) {\n const n = /** @type {any} */ (item.node)\n if (n.drawMode !== 'triangles' || !n.geometry.vertexCount) continue\n const box = n.geometry.bounds, center = box.getCenter(), radius = box.getRadius()\n const cut = item.clip ? { plane: item.clip.plane, cap: !!item.clip.cap } : null\n /** @param {Float32Array} world @param {number | null} instance */\n const add = (world, instance) => {\n const c = center.clone().applyMatrix4(world)\n const scale = Math.max(Math.hypot(world[0], world[1], world[2]), Math.hypot(world[4], world[5], world[6]), Math.hypot(world[8], world[9], world[10]))\n out.push({ node: n, world, instance, cut, x: c[0], y: c[1], z: c[2], radius: radius * scale })\n }\n if (item.instances) {\n for (let i = 0; i < item.instances.count; i++) {\n add(mat4.multiply(new Float32Array(16), item.worldMatrix, item.instances.instanceMatrices.subarray(i * 16, i * 16 + 16)), i)\n }\n } else add(Float32Array.from(item.worldMatrix), null)\n }\n return out\n }\n\n /** @internal\n * Whether the ray meets any of these solids nearer than `distance` - the first one found settles it,\n * so nothing is sorted. One node, or one instance of it, can be left out: what a label is on.\n * @param {Solid[]} solids from Raycaster.solids() @param {number} distance\n * @param {Node | null} [skip] @param {number | null} [skipInstance] null for the whole node\n * @returns {boolean}\n */\n blocked(solids, distance, skip = null, skipInstance = null) {\n const o = this.ray.origin, d = this.ray.direction\n /** @type {Hit[]} */\n const hits = []\n for (const s of solids) {\n if (s.node === skip && (skipInstance === null || s.instance === skipInstance)) continue\n // its bounding sphere first: missed, or wholly beyond the distance or behind the ray, it can't block\n const ox = s.x - o[0], oy = s.y - o[1], oz = s.z - o[2]\n const along = ox * d[0] + oy * d[1] + oz * d[2]\n const off = ox * ox + oy * oy + oz * oz - along * along, r2 = s.radius * s.radius\n if (off > r2) continue\n const half = Math.sqrt(r2 - off)\n if (along - half > distance || along + half < 0) continue\n hits.length = 0\n this.#mesh(s.node, s.world, s.instance, hits, s.cut)\n if (hits.length && hits[0].distance < distance) return true\n }\n return false\n }\n\n /** @internal\n * Where the ray meets one instance, point or segment of a drawable - the CPU half of GPU picking,\n * which finds what is under the pointer and leaves the exact point, face and uv to this.\n * @param {Node} node a Mesh, InstancedMesh, Points or Lines\n * @param {number} element the instance, point or segment (ignored for a plain Mesh)\n * @returns {Hit | null}\n */\n intersectElement(node, element) {\n node.updateWorld()\n const n = /** @type {any} */ (node)\n /** @type {Hit[]} */\n const hits = []\n const cut = cutBy(clipOwner(node))\n if (n.drawMode === 'triangles' && n.instanceMatrices) {\n if (element >= n.count) return null\n mat4.multiply(instanceWorld, n.worldMatrix, n.instanceMatrices.subarray(element * 16, element * 16 + 16))\n this.#mesh(n, instanceWorld, element, hits, cut)\n } else if (n.drawMode === 'triangles') {\n this.#mesh(n, n.worldMatrix, null, hits, cut)\n } else if (n.drawMode === 'points') {\n const p = n.geometry.positions\n if (element >= n.geometry.drawnVertices) return null\n const point = new Vec3(p[element * 3], p[element * 3 + 1], p[element * 3 + 2]).applyMatrix4(n.worldMatrix)\n hits.push({ node: n, point, distance: point.distanceTo(this.ray.origin), normal: null, face: element, instance: null, uv: null, datum: n.datumAt(element) })\n } else if (n.drawMode === 'lines') {\n const g = n.geometry, p = g.positions, idx = g.indices\n const i0 = idx ? idx[element * 2] : element * 2, i1 = idx ? idx[element * 2 + 1] : element * 2 + 1\n if (i1 >= g.vertexCount) return null\n a.set(p[i0 * 3], p[i0 * 3 + 1], p[i0 * 3 + 2]).applyMatrix4(n.worldMatrix)\n b.set(p[i1 * 3], p[i1 * 3 + 1], p[i1 * 3 + 2]).applyMatrix4(n.worldMatrix)\n const { t } = this.ray.distanceSqToSegment(a, b)\n hits.push({ node: n, point: this.ray.at(t), distance: t, normal: null, face: element, instance: null, uv: null, datum: n.datumAt(element) })\n }\n return hits[0] ?? null\n }\n\n /** @param {Node} node @param {Hit[]} hits @param {Cut | null} cut the plane cutting this subtree, from above */\n #visit(node, hits, cut) {\n if (!(this.camera ? node.shownTo(this.camera) : node.visible) || !node.pickable) return\n if (node.clip) cut = cutBy(node)\n const n = /** @type {any} */ (node)\n if (n.drawMode === 'triangles' && n.instanceMatrices) {\n for (let i = 0; i < n.count; i++) {\n mat4.multiply(instanceWorld, n.worldMatrix, n.instanceMatrices.subarray(i * 16, i * 16 + 16))\n this.#mesh(n, instanceWorld, i, hits, cut)\n }\n } else if (n.drawMode === 'triangles') {\n this.#mesh(n, n.worldMatrix, null, hits, cut)\n } else if (n.drawMode === 'points') {\n this.#points(n, hits)\n } else if (n.drawMode === 'lines') {\n this.#lines(n, hits)\n }\n for (const child of node.children) this.#visit(child, hits, cut)\n }\n\n /**\n * @param {Mesh} mesh @param {Float32Array} world @param {number | null} instance @param {Hit[]} hits\n * @param {Cut | null} [cut] what is past it isn't there; with a cap, the faces behind the cut are\n */\n #mesh(mesh, world, instance, hits, cut = null) {\n const g = mesh.geometry\n if (!g.vertexCount) return\n // cheap rejection first\n const box = g.bounds\n const center = box.getCenter().applyMatrix4(world)\n const scale = Math.max(Math.hypot(world[0], world[1], world[2]), Math.hypot(world[4], world[5], world[6]), Math.hypot(world[8], world[9], world[10]))\n if (this.ray.intersectSphere(center, box.getRadius() * scale) === null) return\n if (!mat4.invert(inverse, world)) return\n\n // test in the mesh's own space, then report in world space\n const local = this.ray.clone().applyMatrix4(inverse)\n const p = g.positions, idx = g.indices\n // a cap shows the backs of faces through the cut, so they can be hit too\n const cullBack = !mesh.material.doubleSided && !cut?.cap\n // the plane in the mesh's own space: [n, d] times the world matrix\n if (cut) for (let j = 0; j < 4; j++) localPlane[j] = cut.plane[0] * world[j * 4] + cut.plane[1] * world[j * 4 + 1] + cut.plane[2] * world[j * 4 + 2] + cut.plane[3] * world[j * 4 + 3]\n const o = local.origin, d = local.direction\n let best = null, bestT = Infinity, bestFace = -1\n /** @param {number} f a triangle @returns {number} the nearest hit so far */\n const test = (f) => {\n const i0 = idx ? idx[f * 3] : f * 3, i1 = idx ? idx[f * 3 + 1] : f * 3 + 1, i2 = idx ? idx[f * 3 + 2] : f * 3 + 2\n a.set(p[i0 * 3], p[i0 * 3 + 1], p[i0 * 3 + 2])\n b.set(p[i1 * 3], p[i1 * 3 + 1], p[i1 * 3 + 2])\n c.set(p[i2 * 3], p[i2 * 3 + 1], p[i2 * 3 + 2])\n const hit = local.intersectTriangle(a, b, c, cullBack)\n // a hit on the cut-away side isn't there\n if (hit && cut && localPlane[0] * (o[0] + d[0] * hit.t) + localPlane[1] * (o[1] + d[1] * hit.t) + localPlane[2] * (o[2] + d[2] * hit.t) + localPlane[3] > 0) return bestT\n if (hit && (hit.t < bestT || (hit.t === bestT && f < bestFace))) {\n best = { ...hit, i0, i1, i2 }\n bestT = hit.t\n bestFace = f\n }\n return bestT\n }\n const triangles = Math.floor(g.drawnCount / 3)\n // big meshes through their tree; small ones a triangle at a time\n if (triangles >= BVH_MIN_TRIANGLES) walk(bvhOf(g, triangles), o, d, test)\n else for (let f = 0; f < triangles; f++) test(f)\n if (!best) return\n\n let point = local.at(best.t).applyMatrix4(world)\n // face normal from the local triangle, into world space with the normal matrix\n a.set(p[best.i0 * 3], p[best.i0 * 3 + 1], p[best.i0 * 3 + 2])\n b.set(p[best.i1 * 3], p[best.i1 * 3 + 1], p[best.i1 * 3 + 2]).sub(a)\n c.set(p[best.i2 * 3], p[best.i2 * 3 + 1], p[best.i2 * 3 + 2]).sub(a)\n const n = b.clone().cross(c)\n const normalMatrix = mat3.normalFromMat4(new Float32Array(9), world)\n let normal = normalMatrix ? new Vec3(\n normalMatrix[0] * n[0] + normalMatrix[3] * n[1] + normalMatrix[6] * n[2],\n normalMatrix[1] * n[0] + normalMatrix[4] * n[1] + normalMatrix[7] * n[2],\n normalMatrix[2] * n[0] + normalMatrix[5] * n[1] + normalMatrix[8] * n[2]).normalize() : null\n // a face seen from behind through a capped cut: what was hit is the cut face, on the plane\n if (cut?.cap && normal && normal.dot(this.ray.direction) > 0) {\n const P = cut.plane, { origin, direction } = this.ray\n const across = P[0] * direction[0] + P[1] * direction[1] + P[2] * direction[2]\n if (across < 0) point = this.ray.at(-(P[0] * origin[0] + P[1] * origin[1] + P[2] * origin[2] + P[3]) / across)\n normal = new Vec3(P[0], P[1], P[2])\n }\n\n /** @type {[number, number] | null} */\n let uv = null\n if (g.uvs) {\n const w = 1 - best.u - best.v, t = g.uvs\n uv = [\n w * t[best.i0 * 2] + best.u * t[best.i1 * 2] + best.v * t[best.i2 * 2],\n w * t[best.i0 * 2 + 1] + best.u * t[best.i1 * 2 + 1] + best.v * t[best.i2 * 2 + 1],\n ]\n }\n // a row per vertex (a surface): the row of the hit triangle's nearest corner\n let datum = mesh.datumAt(instance)\n if (instance === null && Array.isArray(mesh.data) && mesh.data.length === g.vertexCount) {\n const w0 = 1 - best.u - best.v\n datum = mesh.data[w0 >= best.u && w0 >= best.v ? best.i0 : best.u >= best.v ? best.i1 : best.i2] ?? null\n }\n hits.push({ node: mesh, point, distance: point.distanceTo(this.ray.origin), normal, face: bestFace, instance, uv, datum })\n }\n\n /** @param {Points} node @param {Hit[]} hits */\n #points(node, hits) {\n const p = node.geometry.positions, w = node.worldMatrix\n const limit = this.threshold * this.threshold\n let best = null\n for (let i = 0, n = node.geometry.drawnVertices; i < n; i++) {\n a.set(p[i * 3], p[i * 3 + 1], p[i * 3 + 2]).applyMatrix4(w)\n const { distanceSq } = this.ray.distanceSqToPoint(a)\n if (distanceSq > limit) continue\n const distance = a.distanceTo(this.ray.origin)\n if (!best || distance < best.distance) best = { node, point: a.clone(), distance, normal: null, face: i, instance: null, uv: null, datum: node.datumAt(i) }\n }\n if (best) hits.push(best)\n }\n\n /** @param {Lines} node @param {Hit[]} hits */\n #lines(node, hits) {\n const g = node.geometry, p = g.positions, idx = g.indices, w = node.worldMatrix\n const limit = this.threshold * this.threshold\n let best = null\n for (let s = 0, n = Math.floor(g.drawnCount / 2); s < n; s++) {\n const i0 = idx ? idx[s * 2] : s * 2, i1 = idx ? idx[s * 2 + 1] : s * 2 + 1\n a.set(p[i0 * 3], p[i0 * 3 + 1], p[i0 * 3 + 2]).applyMatrix4(w)\n b.set(p[i1 * 3], p[i1 * 3 + 1], p[i1 * 3 + 2]).applyMatrix4(w)\n const { distanceSq, t } = this.ray.distanceSqToSegment(a, b)\n if (distanceSq > limit) continue\n if (!best || t < best.distance) best = { node, point: this.ray.at(t), distance: t, normal: null, face: s, instance: null, uv: null, datum: node.datumAt(s) }\n }\n if (best) hits.push(best)\n }\n}\n","// Picking an area of the canvas: everything whose place on screen falls inside a box or a lasso drawn\n// over it - each point, instance and line segment on its own, and a mesh by its middle. Positions\n// are tested, not surfaces, so what is hidden behind other things is found too: selecting a region\n// of a scatter takes the whole region, front to back.\nimport * as mat4 from './math/mat4.js'\nimport { hiddenInstance } from './scene/drawables.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { describe, fail } from './validate.js'\n\n/** @import { Hit } from './Raycaster.js' */\n/** @import { Node } from './scene/Node.js' */\n/** @import { Camera } from './scene/cameras.js' */\n\n/**\n * A box on the canvas, CSS pixels from its top left - width and height may be negative, as a drag\n * up or left makes them - or a lasso: the points of a polygon, [x, y] each.\n * @typedef {{ x: number, y: number, width: number, height: number } | [number, number][]} PickArea\n */\n\nconst instanceWorld = new Float32Array(16)\n\n/**\n * The polygon an area is, and its bounding box, for the inside test.\n * @param {PickArea} area\n * @returns {{ points: number[], left: number, top: number, right: number, bottom: number }}\n */\nfunction outline(area) {\n /** @type {number[]} */\n let points\n if (Array.isArray(area)) {\n if (area.length < 3 || !area.every((p) => Array.isArray(p) && p.length === 2 && p.every(Number.isFinite))) {\n fail('View', `pickArea() takes a box { x, y, width, height } or a lasso of three or more [x, y] points, got ${describe(area)}`)\n }\n points = area.flat()\n } else {\n const { x, y, width, height } = area ?? /** @type {any} */ ({})\n if (![x, y, width, height].every(Number.isFinite)) {\n fail('View', `pickArea() takes a box { x, y, width, height } or a lasso of three or more [x, y] points, got ${describe(area)}`)\n }\n points = [x, y, x + width, y, x + width, y + height, x, y + height]\n }\n let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity\n for (let i = 0; i < points.length; i += 2) {\n left = Math.min(left, points[i])\n right = Math.max(right, points[i])\n top = Math.min(top, points[i + 1])\n bottom = Math.max(bottom, points[i + 1])\n }\n return { points, left, top, right, bottom }\n}\n\n/** Is (x, y) inside the polygon? Even-odd crossings. @param {number[]} p @param {number} x @param {number} y */\nfunction inside(p, x, y) {\n let into = false\n for (let i = 0, j = p.length - 2; i < p.length; j = i, i += 2) {\n const yi = p[i + 1], yj = p[j + 1]\n if ((yi > y) !== (yj > y) && x < p[i] + (p[j] - p[i]) * (y - yi) / (yj - yi)) into = !into\n }\n return into\n}\n\n/**\n * Everything in the scene the camera shows, pickable, whose place falls inside the area - nearest\n * the camera first.\n * @param {Node} scene @param {Camera} camera @param {Float32Array} viewProjection\n * @param {number} width @param {number} height the canvas, CSS pixels\n * @param {PickArea} area\n * @returns {Hit[]}\n */\nexport function pickArea(scene, camera, viewProjection, width, height, area) {\n const shape = outline(area)\n const eye = camera.worldPosition\n const m = viewProjection\n /** @type {Hit[]} */\n const hits = []\n /** World position (x, y, z) inside the area? @param {number} x @param {number} y @param {number} z */\n const within = (x, y, z) => {\n const w = m[3] * x + m[7] * y + m[11] * z + m[15]\n if (w <= 0) return false\n const nz = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w\n if (nz < -1 || nz > 1) return false\n const sx = ((m[0] * x + m[4] * y + m[8] * z + m[12]) / w * 0.5 + 0.5) * width\n const sy = (0.5 - (m[1] * x + m[5] * y + m[9] * z + m[13]) / w * 0.5) * height\n return sx >= shape.left && sx <= shape.right && sy >= shape.top && sy <= shape.bottom && inside(shape.points, sx, sy)\n }\n /** @param {any} node @param {number} x @param {number} y @param {number} z @param {number | null} face @param {number | null} instance */\n const hit = (node, x, y, z, face, instance) => {\n const point = new Vec3(x, y, z)\n hits.push({ node, point, distance: point.distanceTo(eye), normal: null, face, instance, uv: null, datum: node.datumAt(instance ?? face) })\n }\n const p = new Vec3()\n\n /** @param {Node} node */\n const visit = (node) => {\n if (!node.shownTo(camera) || !node.pickable) return\n const n = /** @type {any} */ (node)\n if (n.isDrawable && n.geometry.vertexCount) {\n const g = n.geometry, world = n.worldMatrix\n if (n.drawMode === 'points') {\n const pos = g.positions\n for (let i = 0; i < g.drawnVertices; i++) {\n p.set(pos[i * 3], pos[i * 3 + 1], pos[i * 3 + 2]).applyMatrix4(world)\n if (within(p[0], p[1], p[2])) hit(n, p[0], p[1], p[2], i, null)\n }\n } else if (n.drawMode === 'lines') {\n // a segment by its middle\n const pos = g.positions, idx = g.indices\n for (let s = 0; s < Math.floor(g.drawnCount / 2); s++) {\n const a = idx ? idx[s * 2] : s * 2, b = idx ? idx[s * 2 + 1] : s * 2 + 1\n p.set((pos[a * 3] + pos[b * 3]) / 2, (pos[a * 3 + 1] + pos[b * 3 + 1]) / 2, (pos[a * 3 + 2] + pos[b * 3 + 2]) / 2).applyMatrix4(world)\n if (within(p[0], p[1], p[2])) hit(n, p[0], p[1], p[2], s, null)\n }\n } else if (n.instanceMatrices) {\n // each instance by the middle of its copy of the geometry; hidden ones aren't there\n const centre = g.bounds.getCenter()\n for (let i = 0; i < n.count; i++) {\n if (hiddenInstance(n.instanceMatrices, i)) continue\n mat4.multiply(instanceWorld, world, n.instanceMatrices.subarray(i * 16, i * 16 + 16))\n p.copy(centre).applyMatrix4(instanceWorld)\n if (within(p[0], p[1], p[2])) hit(n, p[0], p[1], p[2], null, i)\n }\n } else {\n p.copy(g.bounds.getCenter()).applyMatrix4(world)\n if (within(p[0], p[1], p[2])) hit(n, p[0], p[1], p[2], null, null)\n }\n }\n for (const child of node.children) visit(child)\n }\n visit(scene)\n return hits.sort((a, b) => a.distance - b.distance)\n}\n","// Change detection for on-demand rendering. Each frame the View lays out a flat signature of\n// everything that affects the picture - transforms, visibility, geometry and instance versions,\n// material values, lights, labels, the camera - and draws only when it differs from the last one.\n// It costs a few numbers per node, so an idle view does almost no work.\n\n/** @import { Scene } from './scene/Scene.js' */\n/** @import { Camera } from './scene/cameras.js' */\n\n// object identity as a number, so swapping a geometry, material or texture counts as a change\n/** @type {WeakMap<object, number>} */\nconst ids = new WeakMap()\nlet nextId = 1\n/** Does a material's shader hook read the clock? @param {{ vertex: string, fragment: string, lit: string }} h */\nexport const usesTime = (h) => /\\buTime\\b/.test(h.vertex + h.fragment + h.lit)\n/** @param {object} o */\nconst idOf = (o) => {\n let id = ids.get(o)\n if (id === undefined) ids.set(o, id = nextId++)\n return id\n}\n\nexport class ChangeWatch {\n #values = new Float64Array(256)\n #previous = new Float64Array(256)\n #count = 0\n #previousCount = -1\n /** @type {string[]} */ #strings = []\n /** @type {string[]} */ #previousStrings = []\n #time = 0\n\n /**\n * Has anything that affects the picture changed since the last call? The first call says yes.\n * @param {Scene} scene\n * @param {Camera} camera\n * @param {number} [time] the View's clock, which shader hooks reading uTime follow\n * @returns {boolean}\n */\n changed(scene, camera, time = 0) {\n this.#time = time\n this.#count = 0\n this.#strings = []\n this.#camera(camera)\n this.#scene(scene, camera)\n\n let changed = this.#count !== this.#previousCount || this.#strings.length !== this.#previousStrings.length\n for (let i = 0; !changed && i < this.#count; i++) changed = this.#values[i] !== this.#previous[i]\n for (let i = 0; !changed && i < this.#strings.length; i++) changed = this.#strings[i] !== this.#previousStrings[i]\n\n // keep this signature as the one to compare against next time\n ;[this.#previous, this.#values] = [this.#values, this.#previous]\n this.#previousCount = this.#count\n this.#previousStrings = this.#strings\n return changed\n }\n\n /** Forget the last signature, so the next check reports a change. */\n reset() {\n this.#previousCount = -1\n }\n\n /** @param {number} v */\n #push(v) {\n if (this.#count === this.#values.length) {\n const grown = new Float64Array(this.#values.length * 2)\n grown.set(this.#values)\n this.#values = grown\n const previous = new Float64Array(grown.length)\n previous.set(this.#previous)\n this.#previous = previous\n }\n this.#values[this.#count++] = v\n }\n\n /** @param {ArrayLike<number>} a */\n #pushAll(a) {\n for (let i = 0; i < a.length; i++) this.#push(a[i])\n }\n\n /** @param {any} camera */\n #camera(camera) {\n this.#push(idOf(camera))\n this.#pushAll(camera.position)\n this.#pushAll(camera.quaternion)\n if (camera.target) this.#pushAll(camera.target)\n this.#push(camera.fov ?? camera.height)\n this.#push(camera.near)\n this.#push(camera.far)\n this.#push(camera.aspect)\n }\n\n /** @param {any} scene @param {any} camera */\n #scene(scene, camera) {\n const bg = scene.background\n if (!bg) this.#push(-1)\n else if ('getHex' in bg) this.#pushAll(bg)\n else this.#texture(bg)\n const env = scene.environment\n if (typeof env === 'string') this.#strings.push(env)\n else this.#texture(env)\n this.#push(scene.environmentIntensity)\n this.#push(scene.backgroundBlur)\n const fog = scene.fog\n if (fog) {\n this.#pushAll(fog.color)\n this.#push(fog.density)\n this.#push(fog.near)\n this.#push(fog.far)\n } else this.#push(-1)\n this.#node(scene, camera)\n }\n\n /** @param {any} node @param {any} camera */\n #node(node, camera) {\n this.#push(idOf(node))\n const shown = node.shownTo(camera)\n this.#push(shown ? 1 : 0)\n // subtrees this camera doesn't draw don't matter until they show again\n if (!shown) return\n this.#push(node.overlay ? idOf(node.overlay) : 0)\n // a section plane moving or changing colour\n const clip = node.clip\n if (clip) {\n this.#pushAll(clip.normal)\n this.#push(clip.offset)\n this.#push(clip.cap ? clip.cap.getHex() : -1)\n } else this.#push(-2)\n // which pointer handlers it has: the frame says whether anything can be clicked or dragged\n this.#push((node.handlersFor('click').length ? 1 : 0) | (node.handlersFor('hover').length ? 2 : 0) | (node.tooltip ? 4 : 0) | (node.onDrag ? 8 : 0) | (node.highlightWhole ? 16 : 0))\n // what hovering tints it with - a different colour shows straight away on what is hovered\n if (node.highlight) this.#pushAll(node.highlight)\n else this.#push(node.highlight === false ? -5 : -4)\n const outline = node.outline\n if (outline) {\n this.#pushAll(outline.color)\n this.#push(outline.width)\n } else this.#push(-3)\n this.#pushAll(node.position)\n this.#pushAll(node.quaternion)\n this.#pushAll(node.scale)\n // a node that keeps its own matrix is moved by editing it\n if (!node.matrixAutoUpdate) this.#pushAll(node.matrix)\n if (node.isDrawable) this.#drawable(node)\n else if (node.isLabel) this.#label(node)\n else if (node.lightKind) this.#light(node)\n for (const child of node.children) this.#node(child, camera)\n }\n\n /** @param {any} node */\n #drawable(node) {\n const g = node.geometry, m = node.material\n this.#push(idOf(g))\n this.#push(g.version)\n this.#push(g.drawCount ?? -1)\n this.#push(node.renderOrder)\n this.#push((node.castShadow ? 1 : 0) | (node.receiveShadow ? 2 : 0) | (node.sort ? 4 : 0))\n if ('arrowBits' in node) {\n this.#push(node.arrowBits)\n this.#push(node.arrowSize)\n }\n // per-instance labels come from these, so swapping either redraws\n this.#push(node.labels ? idOf(node.labels) : 0)\n this.#push(node.data && typeof node.data === 'object' ? idOf(node.data) : 0)\n if ('instanceMatrices' in node) {\n this.#push(node.count)\n this.#push(node.version)\n }\n this.#push(idOf(m))\n this.#pushAll(m.color)\n this.#pushAll(m.emissive)\n this.#push(m.emissiveIntensity)\n this.#push(m.opacity)\n this.#push(m.roughness)\n this.#push(m.metalness)\n this.#push(m.size)\n this.#push(m.width)\n this.#push(m.dash)\n this.#push(m.gap)\n this.#push(m.dashOffset)\n this.#push(m.alphaTest)\n this.#push(m.normalScale)\n this.#push(m.aoMapIntensity)\n this.#push(m.triplanar)\n this.#push(m.bumpScale)\n this.#push(m.transmission)\n this.#push(m.clearcoat)\n this.#push(m.clearcoatRoughness)\n this.#push(m.sheen)\n this.#pushAll(m.sheenColor)\n this.#push(m.sheenRoughness)\n this.#push(m.ior)\n this.#push(m.specularIntensity)\n this.#pushAll(m.specularColor)\n this.#push(m.anisotropy)\n this.#push(m.anisotropyRotation)\n this.#push(m.translucency)\n this.#push(m.toon)\n this.#push(m.lightMapIntensity)\n this.#push(m.environmentIntensity)\n this.#pushAll(m.translucencyColor)\n this.#push((m.unlit ? 1 : 0) | (m.flatShading ? 2 : 0) | (m.doubleSided ? 4 : 0) | (m.vertexColors ? 8 : 0) |\n (m.depthWrite ? 16 : 0) | (m.depthTest ? 32 : 0) | (m.sizeAttenuation ? 64 : 0) | (m.blending === 'additive' ? 128 : m.blending === 'multiply' ? 1024 : 0) | (m.transparent ? 256 : 0) | (m.fog ? 512 : 0))\n for (const [, texture] of m.allTextures) this.#texture(texture)\n const hooks = m.shader\n if (hooks) {\n this.#push(idOf(hooks))\n for (const v of Object.values(hooks.uniforms)) {\n if (typeof v === 'number') this.#push(v)\n // numbers and colours - textures count through their versions, above\n else if (Array.isArray(v) || ArrayBuffer.isView(v)) this.#pushAll(/** @type {ArrayLike<number>} */ (v))\n }\n // a hook that reads the clock moves on its own while time runs\n if (usesTime(hooks)) this.#push(this.#time)\n }\n }\n\n /** @param {any} texture */\n #texture(texture) {\n this.#push(idOf(texture))\n this.#push(texture.version)\n this.#pushAll(texture.repeat)\n this.#push(texture.rotation)\n this.#pushAll(texture.center)\n this.#push(texture.uvSet)\n this.#pushAll(texture.offset)\n }\n\n /** @param {any} label */\n #label(label) {\n this.#strings.push(label.text, label.className, label.place, label.overlap, label.edge ?? '')\n this.#pushAll(label.offset)\n this.#push(label.priority)\n this.#push(label.occlude ? 1 : 0)\n this.#push(label.leader ? 1 : 0)\n this.#push(label.minScale)\n }\n\n /** @param {any} light */\n #light(light) {\n this.#pushAll(light.color)\n this.#push(light.intensity)\n if (light.ground) this.#pushAll(light.ground)\n if (light.direction) this.#pushAll(light.direction)\n if (light.target) this.#pushAll(light.target)\n if (light.castShadow) this.#push(1)\n if (light.shadowBounds) {\n this.#pushAll(light.shadowBounds.min)\n this.#pushAll(light.shadowBounds.max)\n }\n if ('range' in light) this.#push(light.range)\n if ('angle' in light) {\n this.#push(light.angle)\n this.#push(light.penumbra)\n }\n }\n}\n","// Fog: what is further away fades into a colour - a misty harbour, a hazy city, depth in a big\n// scene. Set a scene's fog and its background to the same colour, and distant things melt into it.\nimport { Color } from './value/Color.js'\nimport { checkNumber, checkOptions, describe, fail } from './validate.js'\n\n/** @import { ColorInput } from './types.js' */\n\n/**\n * @typedef {object} FogOptions\n * @property {ColorInput} [color] what distant things fade to - usually the background (default '#808080')\n * @property {number} [density] exponential fog, thickening with distance, as mist does: about how much\n * it hides per unit of distance (try 0.02 - 0.1). The default, unless near and far are given (0.05)\n * @property {number} [near] linear fog instead: the distance it starts at\n * @property {number} [far] linear fog: the distance where everything is fog colour\n */\n\nexport const FOG_OPTIONS = ['color', 'density', 'near', 'far']\nexport const FOG_HINTS = {\n start: \"use 'near' for where linear fog starts\",\n end: \"use 'far' for where linear fog is complete\",\n type: \"give 'density' for exponential fog, or 'near' and 'far' for linear\",\n exp2: \"give 'density' for exponential fog\",\n colour: \"use 'color'\",\n}\n\n/** A scene's fog: change its numbers in place to thicken or thin it. */\nexport class Fog {\n /** What distant things fade to. @type {Color} */ color = new Color(0x808080)\n /** Exponential fog's density, or 0 when the fog is linear. */ density = 0.05\n /** Linear fog: where it starts. */ near = 0\n /** Linear fog: where it is complete. */ far = 100\n\n /** @param {FogOptions} [options] */\n constructor(options = {}) {\n checkOptions('fog', options, FOG_OPTIONS, FOG_HINTS)\n if (options.color !== undefined) this.color.set(options.color, 'fog')\n const linear = options.near !== undefined || options.far !== undefined\n if (linear && options.density !== undefined) fail('fog', \"give 'density' for exponential fog, or 'near' and 'far' for linear - not both\")\n if (linear) {\n this.density = 0\n if (options.near !== undefined) this.near = checkNumber('fog', 'near', options.near)\n if (options.far !== undefined) this.far = checkNumber('fog', 'far', options.far)\n if (!(this.near >= 0) || !(this.far > this.near)) fail('fog', `'near' must be 0 or more and 'far' beyond it, got near ${this.near}, far ${this.far}`)\n } else if (options.density !== undefined) {\n this.density = checkNumber('fog', 'density', options.density)\n if (!(this.density > 0)) fail('fog', `'density' must be more than 0, got ${this.density}`)\n }\n }\n\n /** Linear (near to far) rather than exponential (density)? */\n get linear() {\n return this.density === 0\n }\n\n /** @internal\n * A Fog from a Fog (returned as is) or options.\n * @param {Fog | FogOptions} input @param {string} [owner]\n * @returns {Fog}\n */\n static fromInput(input, owner = 'fog') {\n if (input instanceof Fog) return input\n if (!input || typeof input !== 'object' || Array.isArray(input)) fail(owner, `'fog' must be { color, density } or { color, near, far }, or null, got ${describe(input)}`)\n return new Fog(input)\n }\n\n /** @returns {FogOptions} */\n toJSON() {\n const color = this.color.getStyle()\n return this.linear ? { color, near: this.near, far: this.far } : { color, density: this.density }\n }\n}\n","import { Color } from '../value/Color.js'\nimport { Texture } from '../material/Texture.js'\nimport { checkNumber, describe, fail } from '../validate.js'\nimport { Fog } from '../fog.js'\nimport { NODE_OPTIONS, Node } from './Node.js'\n\n/** @import { NodeOptions } from './Node.js' */\n/** @import { ColorInput } from '../types.js' */\n/** @import { TextureOptions } from '../material/Texture.js' */\n/** @import { FogOptions } from '../fog.js' */\n\n/** @typedef {'studio' | 'none'} EnvironmentPreset */\n\n/**\n * @typedef {NodeOptions & {\n * background?: ColorInput | Texture | TextureOptions | null,\n * environment?: EnvironmentPreset | string | Texture | TextureOptions,\n * environmentIntensity?: number,\n * backgroundBlur?: number,\n * fog?: FogOptions | Fog | null,\n * }} SceneOptions\n */\n\n/**\n * The root of everything drawn. Each frame the View (or your own loop) calls update() and the\n * renderer draws what it holds.\n */\nexport class Scene extends Node {\n static type = 'scene'\n static get OPTIONS() { return [...NODE_OPTIONS, 'background', 'environment', 'environmentIntensity', 'backgroundBlur', 'fog'] }\n static HINTS = {\n fogColor: \"use fog: { color, density }\",\n lights: \"add lights as children: scene.add(new DirectionalLight({ ... }))\",\n envMap: \"use 'environment': 'studio', or an .hdr url\",\n environmentMap: \"use 'environment': 'studio', or an .hdr url\",\n backgroundBlurriness: \"use 'backgroundBlur' (0-1)\",\n }\n\n /** @type {Color | Texture | null} null = transparent */\n #background = null\n /** Image-based lighting for materials. @type {EnvironmentPreset | Texture} */\n #environment = 'none'\n /** Scales the environment's light. */\n environmentIntensity = 1\n /** 0-1: how blurred a panorama background is drawn - a soft backdrop that doesn't compete. */\n backgroundBlur = 0\n /** @internal Set by the View drawing it, from its reducedMotion: charts' transitions and flows stand still. */\n motionReduced = false\n /** @type {Fog | null} */\n #fog = null\n\n /** @param {SceneOptions} [options] */\n constructor(options = {}) {\n super(options)\n if (options.background !== undefined) this.#setBackground(options.background)\n if (options.environment !== undefined) this.#setEnvironment(options.environment)\n if (options.environmentIntensity !== undefined) this.environmentIntensity = /** @type {number} */ (checkNumber('Scene', 'environmentIntensity', options.environmentIntensity))\n if (options.backgroundBlur !== undefined) this.backgroundBlur = /** @type {number} */ (checkNumber('Scene', 'backgroundBlur', options.backgroundBlur))\n if (options.fog != null) this.#fog = Fog.fromInput(options.fog, 'Scene')\n }\n\n /**\n * Distance fog, or null for none: set { color, density } (exponential, like mist) or\n * { color, near, far } (linear). Give the background the same colour, so distant things melt into\n * it; change its numbers in place to thicken or thin it. Materials with fog: false ignore it.\n * @returns {Fog | null}\n */\n get fog() { return this.#fog }\n /** @param {FogOptions | Fog | null} v */\n set fog(v) {\n this.#fog = v == null ? null : Fog.fromInput(v, 'Scene')\n }\n\n /**\n * A colour, a panorama (an equirectangular texture - often the environment itself), or null for\n * transparent. Assign any colour input. @returns {Color | Texture | null}\n */\n get background() { return this.#background }\n /** @param {ColorInput | Texture | TextureOptions | null} v */\n set background(v) {\n this.#setBackground(v)\n }\n\n /** @param {ColorInput | Texture | TextureOptions | null} v */\n #setBackground(v) {\n if (v == null) this.#background = null\n else if (v instanceof Texture) this.#background = v\n else if (typeof v === 'object' && !Array.isArray(v) && !ArrayBuffer.isView(v)) this.#background = new Texture(/** @type {TextureOptions} */ (v))\n else this.#background = Color.fromInput(/** @type {ColorInput} */ (v), 'Scene')\n }\n\n /**\n * Light from all around, reflected by every lit material: 'studio' (built in, no download),\n * 'none', or an equirectangular HDR image - a .hdr url or a Texture. @returns {EnvironmentPreset | Texture}\n */\n get environment() { return this.#environment }\n /** @param {EnvironmentPreset | string | Texture | TextureOptions} v */\n set environment(v) {\n this.#setEnvironment(v)\n }\n\n /** @param {EnvironmentPreset | string | Texture | TextureOptions} v */\n #setEnvironment(v) {\n if (v === 'studio' || v === 'none') this.#environment = v\n else if (typeof v === 'string' && /[./]/.test(v)) this.#environment = new Texture({ url: v, colorSpace: 'linear', mipmaps: false })\n else if (v instanceof Texture) this.#environment = v\n else if (v && typeof v === 'object') this.#environment = new Texture({ colorSpace: 'linear', mipmaps: false, .../** @type {TextureOptions} */ (v) })\n else fail('Scene', `'environment' must be 'studio', 'none', an .hdr url or a texture, got ${describe(v)}`)\n }\n\n /**\n * Advance one frame: run onUpdate handlers depth first, apply any removals they queued, then\n * bring every world matrix up to date.\n * @param {number} dt seconds since the last frame\n * @param {number} t seconds since the start\n * @returns {this}\n */\n update(dt, t) {\n runHandlers(this, dt, t, new Set())\n this.updateWorldTree()\n return this\n }\n\n /** Resolves when every texture in the scene has loaded. @returns {Promise<void>} */\n get ready() {\n /** @type {Promise<unknown>[]} */\n const waits = []\n if (this.#background instanceof Texture) waits.push(this.#background.ready)\n if (this.#environment instanceof Texture) waits.push(this.#environment.ready)\n this.traverse((n) => /** @type {any} */ (n).isDrawable && waits.push(/** @type {any} */ (n).material.ready()))\n return Promise.all(waits).then(() => {})\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), background: this.#background, environment: this.#environment,\n environmentIntensity: this.environmentIntensity, backgroundBlur: this.backgroundBlur, fog: this.#fog ? this.#fog.toJSON() : null }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = {}\n if (this.#background) {\n const bg = this.#background instanceof Texture ? this.#background.toJSON() : this.#background.toJSON()\n if (bg) json.background = bg\n }\n if (this.#environment !== 'none') {\n const env = typeof this.#environment === 'string' ? this.#environment : this.#environment.toJSON()\n if (env) json.environment = env\n }\n if (this.environmentIntensity !== 1) json.environmentIntensity = this.environmentIntensity\n if (this.backgroundBlur) json.backgroundBlur = this.backgroundBlur\n if (this.#fog) json.fog = this.#fog.toJSON()\n return json\n }\n}\n\n// Handlers run for invisible nodes too - behaviour may be what makes them visible again. Each\n// node's children are copied before they are walked, so handlers can add, remove and move nodes -\n// themselves included - without the walk skipping or losing one; a node that moves to a parent\n// walked later still runs once a frame.\n/** @param {Node} node @param {number} dt @param {number} t @param {Set<Node>} ran */\nfunction runHandlers(node, dt, t, ran) {\n if (node.hasHandlers && !ran.has(node)) {\n ran.add(node)\n node.runHandlers(dt, t)\n }\n const children = node.children\n if (children.length) for (const child of [...children]) runHandlers(child, dt, t, ran)\n}\n","import { Color } from '../value/Color.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { Box3 } from '../value/Box3.js'\nimport { checkNumber, describe, fail } from '../validate.js'\nimport { NODE_OPTIONS, Node, inParentSpace, setPoint } from './Node.js'\n\n/** @import { NodeOptions } from './Node.js' */\n/** @import { Box3Input, ColorInput, Vec3Input } from '../types.js' */\n\n/** @typedef {NodeOptions & { color?: ColorInput, intensity?: number }} LightOptions */\n/** @typedef {'ambient' | 'hemisphere' | 'directional' | 'point' | 'spot'} LightKind */\n\nconst LIGHT_OPTIONS = [...NODE_OPTIONS, 'color', 'intensity']\nconst LIGHT_HINTS = {\n distance: \"use 'range' (0 = infinite)\",\n decay: 'falloff is physical (inverse square), as in glTF - limit it with range',\n attenuation: \"use 'range' - falloff is physical (inverse square)\",\n shadow: \"use 'castShadow: true' (directional, spot and point lights)\",\n}\n\n/**\n * Base for lights. Colour and intensity follow glTF's KHR_lights_punctual, so loaded scenes light\n * the same; colours are ordinary colour inputs, the same as materials.\n */\nexport class Light extends Node {\n static OPTIONS = LIGHT_OPTIONS\n static HINTS = LIGHT_HINTS\n /** @internal What kind of light, for renderers - read without importing every light class. @type {LightKind} */\n static kind = 'ambient'\n\n /** @internal @returns {LightKind} */\n get lightKind() {\n return /** @type {typeof Light} */ (this.constructor).kind\n }\n\n #color = new Color(0xffffff)\n intensity = 1\n\n /** @param {LightOptions} [options] */\n constructor(options = {}) {\n super(options)\n const owner = this.constructor.name\n if (options.color !== undefined) this.#color.set(options.color, owner)\n if (options.intensity !== undefined) {\n this.intensity = checkNumber(owner, 'intensity', options.intensity)\n if (this.intensity < 0) fail(owner, `'intensity' can't be negative, got ${this.intensity}`)\n }\n }\n\n /** @returns {Color} */\n get color() { return this.#color }\n /** @param {ColorInput} v */\n set color(v) { this.#color.set(v, this.constructor.name) }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), color: this.#color.clone(), intensity: this.intensity }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = {}\n if (this.#color.getHex() !== 0xffffff) json.color = this.#color.getStyle()\n if (this.intensity !== 1) json.intensity = this.intensity\n return json\n }\n}\n\n/** Light from everywhere equally: lifts the shadows. */\nexport class AmbientLight extends Light {\n static type = 'ambient-light'\n /** @internal @type {LightKind} */\n static kind = 'ambient'\n}\n\n/** Cheap outdoor fill: sky colour from above blending to ground colour from below. */\nexport class HemisphereLight extends Light {\n static type = 'hemisphere-light'\n /** @internal @type {LightKind} */\n static kind = 'hemisphere'\n // 'color' is accepted too: the constructor passes 'sky' on as the base light colour\n static get OPTIONS() { return [...NODE_OPTIONS, 'sky', 'ground', 'intensity', 'color'] }\n\n #ground = new Color(0x444444)\n\n /** @param {NodeOptions & { sky?: ColorInput, ground?: ColorInput, intensity?: number }} [options] */\n constructor(options = {}) {\n const { sky, ground, ...rest } = options\n super(sky !== undefined ? { ...rest, color: sky } : rest)\n if (ground !== undefined) this.#ground.set(ground, 'HemisphereLight')\n }\n\n /** The colour from above (same as `color`). @returns {Color} */\n get sky() { return this.color }\n /** @param {ColorInput} v */\n set sky(v) { this.color.set(v, 'HemisphereLight') }\n /** The colour from below. @returns {Color} */\n get ground() { return this.#ground }\n /** @param {ColorInput} v */\n set ground(v) { this.#ground.set(v, 'HemisphereLight') }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n const { color, ...rest } = super.cloneOptions()\n return { ...rest, sky: color, ground: this.#ground.clone() }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n const { color, ...rest } = super.jsonOptions()\n return { ...rest, ...(color ? { sky: color } : {}), ...(this.#ground.getHex() !== 0x444444 ? { ground: this.#ground.getStyle() } : {}) }\n }\n}\n\n/**\n * @typedef {LightOptions & { direction?: Vec3Input, target?: Vec3Input }} AimedLightOptions\n * direction: the way the light travels; target: a point it shines towards, in the same space as\n * position. Give one or the other.\n */\n\n/** Shared by lights that point somewhere. */\nclass AimedLight extends Light {\n #direction = new Vec3(0, -1, 0)\n /** @type {Vec3 | null} */ #target = null\n\n /** The way the light travels, in the parent's space; ignored when `target` is set. Assigning copies, normalised. @returns {Vec3} */\n get direction() { return this.#direction }\n /** @param {Vec3Input} v */\n set direction(v) {\n const owner = this.constructor.name\n this.#direction.copy(v, owner)\n if (this.#direction.len() === 0) fail(owner, \"'direction' can't be [0, 0, 0]\")\n this.#direction.normalize()\n }\n /** A point to shine towards, in the same space as position; assigning copies, null goes back to direction. @returns {Vec3 | null} */\n get target() { return this.#target }\n /** @param {Vec3Input | null} v */\n set target(v) { this.#target = setPoint(this.#target, v, this.constructor.name) }\n\n /** @param {AimedLightOptions} [options] */\n constructor(options = {}) {\n super(options)\n const owner = this.constructor.name\n if (options.direction !== undefined && options.target !== undefined) {\n fail(owner, \"give 'direction' or 'target', not both\")\n }\n if (options.direction !== undefined) this.direction = options.direction\n if (options.target !== undefined) this.target = options.target\n }\n\n /**\n * Shine at a world position or node: the target moves there, or the direction turns to it. (A\n * light's own rotation doesn't aim it - its direction or target does.)\n * @param {Vec3Input | Node} target\n * @returns {this}\n */\n lookAt(target) {\n const at = inParentSpace(this, target)\n if (this.target) this.target.copy(at)\n else if (!at.equals(this.position, 1e-9)) this.direction.copy(at.sub(this.position).normalize())\n return this\n }\n\n /** The light's direction in world space, as of the last update. @returns {Vec3} */\n get worldDirection() {\n const local = this.target ? this.target.clone().sub(this.position) : this.direction.clone()\n const m = this.parent ? this.parent.worldMatrix : null\n if (m) {\n // directions transform without translation\n const [x, y, z] = local\n local.set(m[0] * x + m[4] * y + m[8] * z, m[1] * x + m[5] * y + m[9] * z, m[2] * x + m[6] * y + m[10] * z)\n }\n return local.normalize()\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), ...(this.target ? { target: this.target.toArray() } : { direction: this.direction.toArray() }) }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.target ? { target: this.target.toArray() } : { direction: this.direction.toArray() }) }\n }\n}\n\n/** Parallel light from far away, like the sun. Position only matters for its shadow. */\nexport class DirectionalLight extends AimedLight {\n static type = 'directional-light'\n /** @internal @type {LightKind} */\n static kind = 'directional'\n static get OPTIONS() { return [...LIGHT_OPTIONS, 'direction', 'target', 'castShadow', 'shadowBounds'] }\n\n castShadow = false\n /** @type {Box3 | null} */\n #shadowBounds = null\n\n /** @param {AimedLightOptions & { castShadow?: boolean, shadowBounds?: Box3Input | null }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.castShadow !== undefined) this.castShadow = !!options.castShadow\n if (options.shadowBounds !== undefined) this.#setShadowBounds(options.shadowBounds)\n }\n\n /**\n * The part of the world, in world units, that has shadows - or null (the default) to follow\n * whatever casts them. The shadow map is fitted to what casts every frame, so one caster flung far\n * off spreads its texels over everything and every shadow blurs; set the area where things happen\n * and its shadows stay sharp. Casters outside it still shadow it, from wherever they stand.\n * Assigning copies.\n * @returns {Box3 | null}\n */\n get shadowBounds() { return this.#shadowBounds }\n\n /** @param {Box3Input | null} v */\n set shadowBounds(v) { this.#setShadowBounds(v) }\n\n /** @param {Box3Input | null} v */\n #setShadowBounds(v) {\n if (v === null) {\n this.#shadowBounds = null\n return\n }\n const b = /** @type {any} */ (v)\n if (!b || typeof b !== 'object' || !b.min || !b.max) {\n fail(this.constructor.name, `'shadowBounds' is a box - { min: [x, y, z], max: [x, y, z] } or a Box3 - or null, got ${describe(v)}`)\n }\n const box = new Box3(Vec3.fromInput(b.min, this.constructor.name), Vec3.fromInput(b.max, this.constructor.name))\n if (box.isEmpty()) fail(this.constructor.name, `'shadowBounds' min must not be above max on any axis, got ${describe(v)}`)\n this.#shadowBounds = box\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), castShadow: this.castShadow, shadowBounds: this.#shadowBounds }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n const b = this.#shadowBounds\n return { ...super.jsonOptions(), ...(this.castShadow ? { castShadow: true } : {}),\n ...(b ? { shadowBounds: { min: Array.from(b.min), max: Array.from(b.max) } } : {}) }\n }\n}\n\n/** Light from a point in all directions, falling off with the square of the distance. */\nexport class PointLight extends Light {\n static type = 'point-light'\n /** @internal @type {LightKind} */\n static kind = 'point'\n static get OPTIONS() { return [...LIGHT_OPTIONS, 'range', 'castShadow'] }\n\n /** Distance where the light fades to nothing; 0 for unlimited. */\n range = 0\n /**\n * Cast shadows all round: one point light a scene can. Everything that casts blocks it, round\n * it too - a lantern's walls, a pumpkin's shell - so light leaves only through the openings; give\n * a bulb or flame drawn at the light castShadow: false.\n */\n castShadow = false\n\n /** @param {LightOptions & { range?: number, castShadow?: boolean }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.range !== undefined) this.range = rangeOf(this.constructor.name, options.range)\n if (options.castShadow !== undefined) this.castShadow = !!options.castShadow\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), range: this.range, castShadow: this.castShadow }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n return { ...super.jsonOptions(), ...(this.range ? { range: this.range } : {}), ...(this.castShadow ? { castShadow: true } : {}) }\n }\n}\n\n/** A cone of light from a point. */\nexport class SpotLight extends AimedLight {\n static type = 'spot-light'\n /** @internal @type {LightKind} */\n static kind = 'spot'\n static get OPTIONS() { return [...LIGHT_OPTIONS, 'direction', 'target', 'range', 'angle', 'penumbra', 'castShadow'] }\n\n range = 0\n /** Cast shadows: up to four spot lights a scene can. Anything round the light itself - its own lamp - doesn't block it. */\n castShadow = false\n /** Half-angle of the cone in radians. */\n angle = Math.PI / 6\n /** Softness of the edge, 0 (hard) to 1. */\n penumbra = 0.1\n\n /** @param {AimedLightOptions & { range?: number, angle?: number, penumbra?: number, castShadow?: boolean }} [options] */\n constructor(options = {}) {\n super(options)\n if (options.castShadow !== undefined) this.castShadow = !!options.castShadow\n if (options.range !== undefined) this.range = rangeOf('SpotLight', options.range)\n if (options.angle !== undefined) {\n this.angle = checkNumber('SpotLight', 'angle', options.angle)\n if (this.angle <= 0 || this.angle > Math.PI / 2) fail('SpotLight', `'angle' is the cone's half-angle in radians, above 0 and up to PI/2, got ${this.angle}`)\n }\n if (options.penumbra !== undefined) {\n this.penumbra = checkNumber('SpotLight', 'penumbra', options.penumbra)\n if (this.penumbra < 0 || this.penumbra > 1) fail('SpotLight', `'penumbra' must be 0-1, got ${this.penumbra}`)\n }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n cloneOptions() {\n return { ...super.cloneOptions(), range: this.range, angle: this.angle, penumbra: this.penumbra, castShadow: this.castShadow }\n }\n\n /** @internal @returns {Record<string, unknown>} */\n jsonOptions() {\n /** @type {Record<string, unknown>} */\n const json = super.jsonOptions()\n if (this.range) json.range = this.range\n if (this.angle !== Math.PI / 6) json.angle = this.angle\n if (this.penumbra !== 0.1) json.penumbra = this.penumbra\n if (this.castShadow) json.castShadow = true\n return json\n }\n}\n\n/** @param {string} owner @param {unknown} v */\nfunction rangeOf(owner, v) {\n const r = checkNumber(owner, 'range', v)\n if (r < 0) fail(owner, `'range' can't be negative (0 means unlimited), got ${r}`)\n return r\n}\n","// Shader hooks for the renderer: a material's GLSL turned into what the shaders splice in - uniform\n// declarations and the code - and the defines that switch it on, one program per distinct hook. A\n// hook that fails to compile is reported once, in terms of its own lines, and the material is drawn\n// without it from then on, rather than stopping the frame.\nimport { Texture } from '../material/Texture.js'\nimport { warnOnce } from '../validate.js'\nimport { CLIP_ONLY_FRAGMENT, HOOK_HELPERS, HOOK_SOURCE_NUMBERS, LINES_VERTEX, MESH_VERTEX, POINTS_VERTEX, shaderSource } from './shaders.js'\n\n/** @import { Material, ShaderUniform } from '../material/Material.js' */\n/** @import { HookSource } from './shaders.js' */\n/** @import { Program } from './programs.js' */\n\n/**\n * A material's hooks, ready to compile.\n * @typedef {object} Hook\n * @property {string} signature its code and uniform types - one program per signature\n * @property {string[]} defines HOOK_VERTEX, HOOK_FRAGMENT, HOOK_LIT for the parts it has, and its id\n * @property {HookSource} source what the shaders splice in\n * @property {boolean} moves it has a vertex hook\n */\n\n/** @type {Map<string, Hook>} */\nconst hooks = new Map()\n/** Signatures that failed to compile: those materials draw without their hooks. @type {Set<string>} */\nconst failed = new Set()\n/** @type {WeakMap<object, { types: string, hook: Hook | null }>} */\nconst recent = new WeakMap()\n\n/** The GLSL type of a uniform's value. @param {ShaderUniform} v */\nfunction glslType(v) {\n if (typeof v === 'number') return 'float'\n if (v instanceof Texture) return 'sampler2D'\n return `vec${/** @type {ArrayLike<number>} */ (v).length}`\n}\n\n// the uniforms phoria2's shaders declare, which a hook's own can't reuse\nlet own = /** @type {Set<string> | null} */ (null)\nconst ownUniforms = () => own ??= new Set([MESH_VERTEX, POINTS_VERTEX, LINES_VERTEX, CLIP_ONLY_FRAGMENT, ...['mesh', 'points', 'lines'].flatMap((k) => shaderSource(/** @type {any} */ (k), []))]\n .flatMap((s) => [...s.matchAll(/uniform\\s+\\w+\\s+(\\w+)/g)].map((m) => m[1])))\n\n/**\n * The hooks a material draws with, or null: none, or ones that failed to compile.\n * @param {Material} material\n * @returns {Hook | null}\n */\nexport function hookFor(material) {\n const s = material.shader\n if (!s) return null\n const types = Object.entries(s.uniforms).map(([k, v]) => `${glslType(v)} ${k}`).join(';')\n const last = recent.get(s)\n if (last && last.types === types) return last.hook\n const signature = JSON.stringify([s.vertex, s.fragment, s.lit, types])\n let hook = failed.has(signature) ? null : hooks.get(signature) ?? null\n if (!hook && !failed.has(signature)) {\n const clash = Object.keys(s.uniforms).find((k) => ownUniforms().has(k))\n if (clash) {\n failed.add(signature)\n warnOnce(material, `shader uniform '${clash}' is one of phoria2's own - give it another name; the material is drawn without its shader hooks`)\n } else {\n hook = {\n signature,\n defines: [...(s.vertex ? ['HOOK_VERTEX'] : []), ...(s.fragment ? ['HOOK_FRAGMENT'] : []), ...(s.lit ? ['HOOK_LIT'] : []), `HOOKS ${hooks.size + 1}`],\n source: {\n uniforms: ['uniform float uTime;', 'uniform vec3 cameraPosition;', ...types.split(';').filter(Boolean).map((t) => `uniform ${t};`)].join('\\n'),\n helpers: HOOK_HELPERS,\n vertex: s.vertex, fragment: s.fragment, lit: s.lit,\n },\n moves: !!s.vertex,\n }\n hooks.set(signature, hook)\n }\n }\n recent.set(s, { types, hook })\n return hook\n}\n\n/**\n * Defines for a pass that isn't the colour pass: the vertex hook always - so a shadow, an outline or\n * a pick is of the moved shape - and the fragment hook only where its discards should cut (meshes'\n * shadows and picks); never the lit hook.\n * @param {Hook} hook @param {boolean} cuts\n */\nexport function passDefines(hook, cuts) {\n return hook.defines.filter((d) => d !== 'HOOK_LIT' && (cuts || d !== 'HOOK_FRAGMENT'))\n}\n\n/**\n * Set the hook's uniforms: the clock, where the camera is, and the material's own values.\n * @param {Program} program @param {Material} material @param {number} time\n * @param {ArrayLike<number>} camera the camera's world position\n * @param {(t: Texture) => WebGLTexture} texture\n */\nexport function setHookUniforms(program, material, time, camera, texture) {\n program.set('uTime', time)\n program.set('cameraPosition', camera)\n const u = /** @type {NonNullable<Material['shader']>} */ (material.shader).uniforms\n for (const name in u) {\n const v = u[name]\n program.set(name, v instanceof Texture ? texture(v) : v)\n }\n}\n\n/**\n * A program built with a material's hooks failed: say why, once, in the hook's own terms, and draw\n * the material without them from now on.\n * @param {Material} material @param {Hook} hook @param {string} log the compiler's\n */\nexport function hookFailed(material, hook, log) {\n failed.add(hook.signature)\n recent.delete(/** @type {object} */ (material.shader))\n const names = Object.fromEntries(Object.entries(HOOK_SOURCE_NUMBERS).map(([part, n]) => [n, part]))\n const lines = log.split('\\n').map((line) => /ERROR:\\s*(\\d+):(\\d+):\\s*(.*)/.exec(line)).filter((m) => !!m)\n const own = lines.filter((m) => names[m[1]])\n const where = own.length\n ? own.map((m) => `shader.${names[m[1]]} line ${m[2]}: ${m[3]}`).join('; ')\n : `in phoria2's shader around the hook: ${lines[0]?.[3] ?? log.trim().split('\\n')[0]}`\n const uniforms = Object.keys(/** @type {NonNullable<Material['shader']>} */ (material.shader).uniforms)\n warnOnce(material, `a shader hook doesn't compile - ${where}. Hooks can use ${HOOK_NAMES}, uTime${uniforms.length ? `, ${uniforms.join(', ')}` : ''}, cameraPosition, and call hash, vnoise, snoise, snoised, vfbm, sfbm, sfbmd, voronoi, srgb, hsv2rgb, palette, fresnel, rotate2, rotate3, remap and saturate. The material is drawn without its hooks`)\n}\n\nconst HOOK_NAMES = 'local, n, uv, index, size, along (vertex); base, emissive, normal, vUv, vWorldPosition, vNormal, vColor, pointUv, distance (fragment); color, base (lit)'\n","// Shader programs, compiled on first use and cached by kind and feature defines. Compiling is the\n// most of a first frame, so it runs in parallel where the browser can (KHR_parallel_shader_compile):\n// programs are started without waiting, drawing skips the ones still compiling, and the renderer\n// draws again when they are done. Nothing waits on a status check until a program is used.\nimport { shaderSource } from './shaders.js'\n\n/** @import { HookSource, ShaderKind } from './shaders.js' */\n\n/**\n * @typedef {object} Program\n * @property {WebGLProgram} program\n * @property {string} key\n * @property {(name: string, value: any) => void} set set a uniform by name (ignored if the shader doesn't use it)\n * @property {number} frame the frame its per-frame uniforms were last set for\n * @property {boolean} ready compiled, linked and its uniforms found\n * @property {string} [failed] the compiler's log, for a program with a material's shader hooks that\n * failed - those are reported and drawn without, rather than thrown\n */\n\n/**\n * @typedef {Program & { shaders: [WebGLShader, WebGLShader], sources: [string, string], hooked: boolean }} Building\n */\n\nexport class Programs {\n /** @type {Map<string, Program>} */ #cache = new Map()\n /** Compiling off the main thread is possible. */\n #parallel\n /** Full-screen passes have no attributes, but still want a vertex array of their own. @type {WebGLVertexArrayObject | null} */\n #empty = null\n\n /** @param {WebGL2RenderingContext} gl */\n constructor(gl) {\n this.gl = gl\n this.#parallel = !!gl.getExtension('KHR_parallel_shader_compile')\n }\n\n get count() {\n return this.#cache.size\n }\n\n /** Programs started but not finished compiling. */\n get compiling() {\n let n = 0\n for (const p of this.#cache.values()) if (!p.ready && !this.isReady(p)) n++\n return n\n }\n\n /**\n * A program, started compiling on first ask. It may not be ready yet - check isReady() before\n * drawing with it, or use ready() to wait.\n * @param {ShaderKind | string} kind a drawable kind, or a pass's name when it brings its sources\n * @param {string[]} defines\n * @param {[string, string]} [sources] a pass's vertex and fragment shaders\n * @param {HookSource | null} [hooks] a material's shader hooks, spliced in (its id is in the defines)\n * @returns {Program}\n */\n get(kind, defines, sources, hooks = null) {\n const key = `${kind}|${defines.join(',')}`\n let p = this.#cache.get(key)\n if (!p) {\n p = this.#start(key, shaderSource(sources ?? /** @type {ShaderKind} */ (kind), defines, hooks), !!hooks)\n this.#cache.set(key, p)\n }\n return p\n }\n\n /**\n * A program, waiting for it to finish compiling if it hasn't - for passes and picking, which\n * need their programs now.\n * @param {ShaderKind | string} kind @param {string[]} defines @param {[string, string]} [sources]\n * @param {HookSource | null} [hooks]\n * @returns {Program}\n */\n ready(kind, defines, sources, hooks = null) {\n const p = this.get(kind, defines, sources, hooks)\n if (!p.ready) this.#finish(/** @type {Building} */ (p))\n return p\n }\n\n /**\n * Has it finished compiling? Asks without waiting, and finishes it (finding its uniforms) once\n * it has.\n * @param {Program} p\n * @returns {boolean}\n */\n isReady(p) {\n if (p.ready) return true\n if (this.#parallel && !this.gl.getProgramParameter(p.program, 0x91b1 /* COMPLETION_STATUS_KHR */)) return false\n this.#finish(/** @type {Building} */ (p))\n return true\n }\n\n /** Forget everything - after a lost context. */\n /** Forget every program - after a lost context, when they are already gone. */\n reset() {\n this.#cache.clear()\n this.#empty = null\n // a lost context drops its extensions: ask again, which turns it back on (or finds it gone)\n this.#parallel = !!this.gl.getExtension('KHR_parallel_shader_compile')\n }\n\n /**\n * Draw one triangle over the whole target with the program in use - a full-screen pass, its corners\n * made in the vertex shader from the vertex index. Depth, culling and blending are the pass's own.\n */\n drawFullscreen() {\n const gl = this.gl\n this.#empty ??= gl.createVertexArray()\n gl.bindVertexArray(this.#empty)\n gl.drawArrays(gl.TRIANGLES, 0, 3)\n }\n\n dispose() {\n for (const p of this.#cache.values()) this.gl.deleteProgram(p.program)\n this.#cache.clear()\n if (this.#empty) this.gl.deleteVertexArray(this.#empty)\n this.#empty = null\n }\n\n /**\n * Start compiling and linking, without asking how it went - that would wait for it.\n * @param {string} key @param {[string, string]} sources @param {boolean} [hooked] has a material's own code\n * @returns {Program}\n */\n #start(key, sources, hooked = false) {\n const gl = this.gl\n const shader = (type, source) => {\n const s = /** @type {WebGLShader} */ (gl.createShader(type))\n gl.shaderSource(s, source)\n gl.compileShader(s)\n return s\n }\n const program = /** @type {WebGLProgram} */ (gl.createProgram())\n const vs = shader(gl.VERTEX_SHADER, sources[0])\n const fs = shader(gl.FRAGMENT_SHADER, sources[1])\n gl.attachShader(program, vs)\n gl.attachShader(program, fs)\n gl.linkProgram(program)\n /** @type {Building} */\n const p = { program, key, frame: -1, ready: false, set() {}, shaders: [vs, fs], sources, hooked }\n // without parallel compiling there is nothing to gain by waiting until it's used\n if (!this.#parallel) this.#finish(p)\n return p\n }\n\n /** Check how compiling went - throwing the log if it failed - and find the uniforms. @param {Building} p */\n #finish(p) {\n const gl = this.gl\n const { program, key, shaders, sources } = p\n if (!gl.getProgramParameter(program, gl.LINK_STATUS) && !gl.isContextLost()) {\n // a material's own code failing is its problem, not the frame's: kept to be reported\n if (p.hooked) {\n p.failed = shaders.map((s) => gl.getShaderParameter(s, gl.COMPILE_STATUS) ? '' : gl.getShaderInfoLog(s) ?? '').join('\\n') || (gl.getProgramInfoLog(program) ?? 'failed to link')\n p.ready = true\n return\n }\n // the shader that failed says why, with its source numbered to match the log\n shaders.forEach((s, i) => {\n if (gl.getShaderParameter(s, gl.COMPILE_STATUS)) return\n throw new Error(`phoria2: ${i ? 'fragment' : 'vertex'} shader '${key}' failed to compile:\\n${gl.getShaderInfoLog(s)}\\n${numbered(sources[i])}`)\n })\n throw new Error(`phoria2: shader program '${key}' failed to link: ${gl.getProgramInfoLog(program)}`)\n }\n for (const s of shaders) gl.deleteShader(s)\n\n // every active uniform, with a setter for its type; arrays are set from flat typed arrays\n /** @type {Map<string, (value: any) => void>} */\n const setters = new Map()\n const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)\n let unit = 0\n for (let i = 0; i < n; i++) {\n const info = /** @type {WebGLActiveInfo} */ (gl.getActiveUniform(program, i))\n const name = info.name.replace(/\\[0\\]$/, '')\n const loc = gl.getUniformLocation(program, info.name)\n const sampler = info.type === gl.SAMPLER_2D || info.type === gl.SAMPLER_2D_SHADOW || info.type === gl.SAMPLER_CUBE_SHADOW\n setters.set(name, setterFor(gl, info.type, loc, sampler ? unit++ : 0))\n }\n p.set = (name, value) => setters.get(name)?.(value)\n p.ready = true\n }\n}\n\n/** @param {WebGL2RenderingContext} gl @param {number} type @param {WebGLUniformLocation | null} loc @param {number} unit */\nfunction setterFor(gl, type, loc, unit) {\n switch (type) {\n case gl.FLOAT: return (v) => typeof v === 'number' ? gl.uniform1f(loc, v) : gl.uniform1fv(loc, v)\n case gl.FLOAT_VEC2: return (v) => gl.uniform2fv(loc, v)\n case gl.FLOAT_VEC3: return (v) => gl.uniform3fv(loc, v)\n case gl.FLOAT_VEC4: return (v) => gl.uniform4fv(loc, v)\n case gl.INT:\n case gl.BOOL: return (v) => gl.uniform1i(loc, v)\n case gl.UNSIGNED_INT: return (v) => gl.uniform1ui(loc, v)\n case gl.FLOAT_MAT3: return (v) => gl.uniformMatrix3fv(loc, false, v)\n case gl.FLOAT_MAT4: return (v) => gl.uniformMatrix4fv(loc, false, v)\n case gl.SAMPLER_2D:\n case gl.SAMPLER_2D_SHADOW: return (texture) => {\n gl.activeTexture(gl.TEXTURE0 + unit)\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.uniform1i(loc, unit)\n }\n case gl.SAMPLER_CUBE_SHADOW: return (texture) => {\n gl.activeTexture(gl.TEXTURE0 + unit)\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture)\n gl.uniform1i(loc, unit)\n }\n default: return () => {}\n }\n}\n\n/** @param {string} source */\nconst numbered = (source) => source.split('\\n').map((line, i) => `${String(i + 1).padStart(4)} ${line}`).join('\\n')\n","// GPU copies of geometry, instance data and textures, created on first use and kept in step with the\n// CPU objects through their `version` counters. Everything is keyed by object in WeakMaps, so a\n// dropped geometry's entry goes with it; dispose() frees the GL objects straight away.\nimport { ATTRIBUTES } from './shaders.js'\nimport { isVideo } from '../material/Texture.js'\n\n/** @import { Geometry } from '../geometry/Geometry.js' */\n/** @import { Texture, DataImage } from '../material/Texture.js' */\n/** @import { Scene } from '../scene/Scene.js' */\n\n// uploads bind textures here, out of the way of the units programs sample from\nconst UPLOAD_UNIT = 15\n// past this many changed regions since the last upload, those in each cell of a GRID x GRID split of\n// the image go as one rectangle round them - nearby changes together, far ones still apart\nconst MOST_REGIONS = 16, GRID = 4\n\n/**\n * @typedef {object} MeshBuffers\n * @property {WebGLVertexArrayObject} vao\n * @property {WebGLBuffer[]} buffers\n * @property {number} count indices or vertices to draw\n * @property {number} indexType gl.UNSIGNED_SHORT / gl.UNSIGNED_INT, or 0 when not indexed\n * @property {Geometry} geometry the geometry they were made from - an instanced mesh can be given another\n * @property {number} version geometry version they were made from\n * @property {number} instanceVersion instance data version (instanced meshes)\n * @property {WebGLBuffer | null} [matrixBuffer] per-instance matrices, refilled when only they change\n * @property {WebGLBuffer | null} [colorBuffer] per-instance colours, likewise\n * @property {Record<string, WebGLBuffer>} [attributes] the geometry's buffers by attribute\n * @property {string} [layout] the data's shape when made; while it holds, changes refill in place\n */\n\n/**\n * The sizes of everything uploaded - equal layouts can reuse the same buffers.\n * @param {Geometry} g\n * @param {{ instanceMatrices: Float32Array, instanceColors: Float32Array | null } | null} instances\n * @param {boolean} withNormals\n */\nfunction layoutOf(g, instances, withNormals, withTangents) {\n return [g.positions.length, withNormals, g.uvs?.length, g.uvs2?.length, g.colors?.length, g.indices?.length,\n instances?.instanceMatrices.length, instances?.instanceColors?.length, withTangents].join()\n}\n\n/**\n * Per-vertex tangents along the UVs' u, with the way v runs in w (Lengyel's method): smooth where\n * the normals are. Without UVs, around the mesh's up axis.\n * @param {Geometry} g\n * @returns {Float32Array}\n */\nexport function tangentsOf(g) {\n const p = g.positions, n = g.normals, uv = g.uvs, count = p.length / 3\n const out = new Float32Array(count * 4)\n const t = new Float32Array(count * 3), b = new Float32Array(count * 3)\n if (uv) {\n const idx = g.indices, triangles = (idx ? idx.length : count) / 3\n for (let k = 0; k < triangles; k++) {\n const i0 = idx ? idx[k * 3] : k * 3, i1 = idx ? idx[k * 3 + 1] : k * 3 + 1, i2 = idx ? idx[k * 3 + 2] : k * 3 + 2\n const e1x = p[i1 * 3] - p[i0 * 3], e1y = p[i1 * 3 + 1] - p[i0 * 3 + 1], e1z = p[i1 * 3 + 2] - p[i0 * 3 + 2]\n const e2x = p[i2 * 3] - p[i0 * 3], e2y = p[i2 * 3 + 1] - p[i0 * 3 + 1], e2z = p[i2 * 3 + 2] - p[i0 * 3 + 2]\n const du1 = uv[i1 * 2] - uv[i0 * 2], dv1 = uv[i1 * 2 + 1] - uv[i0 * 2 + 1]\n const du2 = uv[i2 * 2] - uv[i0 * 2], dv2 = uv[i2 * 2 + 1] - uv[i0 * 2 + 1]\n const det = du1 * dv2 - du2 * dv1\n if (Math.abs(det) < 1e-12) continue\n const r = 1 / det\n const tx = (e1x * dv2 - e2x * dv1) * r, ty = (e1y * dv2 - e2y * dv1) * r, tz = (e1z * dv2 - e2z * dv1) * r\n const bx = (e2x * du1 - e1x * du2) * r, by = (e2y * du1 - e1y * du2) * r, bz = (e2z * du1 - e1z * du2) * r\n for (const i of [i0, i1, i2]) {\n t[i * 3] += tx; t[i * 3 + 1] += ty; t[i * 3 + 2] += tz\n b[i * 3] += bx; b[i * 3 + 1] += by; b[i * 3 + 2] += bz\n }\n }\n }\n for (let i = 0; i < count; i++) {\n const nx = n[i * 3], ny = n[i * 3 + 1], nz = n[i * 3 + 2]\n let tx = t[i * 3], ty = t[i * 3 + 1], tz = t[i * 3 + 2]\n // onto the surface, square to the normal\n const d = nx * tx + ny * ty + nz * tz\n tx -= nx * d; ty -= ny * d; tz -= nz * d\n let len = Math.hypot(tx, ty, tz)\n if (len < 1e-9) {\n // no UVs here: around the up axis, or the x axis for a surface facing up or down\n if (Math.abs(ny) < 0.999) { tx = nz; ty = 0; tz = -nx } else { tx = 1; ty = 0; tz = 0 }\n const e = nx * tx + ny * ty + nz * tz\n tx -= nx * e; ty -= ny * e; tz -= nz * e\n len = Math.hypot(tx, ty, tz) || 1\n }\n out[i * 4] = tx / len; out[i * 4 + 1] = ty / len; out[i * 4 + 2] = tz / len\n // which way v runs against n x t: mirrored UVs turn the other way\n const cx = ny * tz - nz * ty, cy = nz * tx - nx * tz, cz = nx * ty - ny * tx\n out[i * 4 + 3] = cx * b[i * 3] + cy * b[i * 3 + 1] + cz * b[i * 3 + 2] < 0 ? -1 : 1\n }\n return out\n}\n\nconst UV_MATRIX = new Float32Array(9)\n\n/**\n * A map's UV transform as a 3x3 (column-major): repeat, then rotation about its centre, then offset -\n * glTF's KHR_texture_transform order, turning the way three.js and glTF viewers do. Written into one\n * shared array, so set it as a uniform straight away.\n * @param {{ repeat: number[], offset: number[], rotation: number, center: number[] }} t\n * @returns {Float32Array}\n */\nexport function uvMatrix(t) {\n const c = Math.cos(t.rotation), s = Math.sin(t.rotation)\n const [sx, sy] = t.repeat, [cx, cy] = t.center\n const m = UV_MATRIX\n m[0] = c * sx; m[1] = -s * sx; m[2] = 0\n m[3] = s * sy; m[4] = c * sy; m[5] = 0\n m[6] = cx - c * cx - s * cy + t.offset[0]; m[7] = cy + s * cx - c * cy + t.offset[1]; m[8] = 1\n return m\n}\n\n// a quad as a triangle strip of [along, across] corners, shared by every Lines draw\nconst LINE_CORNERS = new Float32Array([0, -1, 0, 1, 1, -1, 1, 1])\n// a point drawn as a square: position, colour, size, opacity, angle and index, as [location, floats,\n// offset in floats]\nconst SPRITE_LAYOUT = [[ATTRIBUTES.position, 3, 0], [ATTRIBUTES.color, 3, 3], [ATTRIBUTES.pointSize, 1, 6],\n [ATTRIBUTES.pointOpacity, 1, 7], [ATTRIBUTES.pointAngle, 1, 8], [ATTRIBUTES.pointIndex, 1, 9]]\nconst SPRITE_STRIDE = 10\n\nexport class Resources {\n /** @type {WebGL2RenderingContext} */ gl\n // one cache per way of drawing, since one geometry can be drawn as triangles, points and lines\n /** @type {WeakMap<object, MeshBuffers>} */ #triangles = new WeakMap()\n /** @type {WeakMap<object, MeshBuffers>} */ #points = new WeakMap()\n /** @type {WeakMap<object, MeshBuffers>} */ #lines = new WeakMap()\n /** Points drawn as squares: an instance a point. @type {WeakMap<object, MeshBuffers & { capacity: number, sorted: boolean, data: Float32Array }>} */ #sprites = new WeakMap()\n /** The GPU copy of each texture: the version it holds, and the storage it was made with. @type {WeakMap<Texture, { texture: WebGLTexture, version: number, width: number, height: number, internal: number }>} */ #textures = new WeakMap()\n /** @type {WebGLTexture | null} */ #white = null\n /** @type {WebGLBuffer | null} */ #corners = null\n /** Counts for renderer.info. */\n counts = { geometries: 0, textures: 0 }\n /** The renderer drawing right now - what it touches is marked as used by it. @type {object | null} */\n owner = null\n // which renderers have drawn each geometry, instanced mesh and texture (a shared context frees\n // one only when no renderer still draws it)\n /** @type {WeakMap<object, Set<object>>} */ #usedBy = new WeakMap()\n\n /** @param {WebGL2RenderingContext} gl */\n constructor(gl) {\n this.gl = gl\n }\n\n /** @type {{ ext: any, max: number } | null | undefined} */\n #aniso\n\n /** The anisotropic filtering extension and its limit, or null where there is none. */\n #anisotropic() {\n if (this.#aniso !== undefined) return this.#aniso\n const ext = this.gl.getExtension('EXT_texture_filter_anisotropic')\n this.#aniso = ext ? { ext, max: this.gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT) || 1 } : null\n return this.#aniso\n }\n\n /**\n * Vertex array for a mesh or points: the geometry's attributes, plus per-instance matrices and\n * colours when `instances` is given. Instanced meshes get their own vertex array, keyed by the node.\n * @param {Geometry} geometry\n * @param {{ instanceMatrices: Float32Array, instanceColors: Float32Array | null, version: number } | null} instances\n * @param {boolean} withNormals\n * @param {boolean} [withTangents] add tangents, for brushed metal - kept once added\n * @returns {MeshBuffers}\n */\n mesh(geometry, instances, withNormals, withTangents = false) {\n const key = instances ?? geometry\n this.#mark(key)\n const cache = withNormals ? this.#triangles : this.#points\n let entry = cache.get(key)\n // instanced buffers are kept by the node, so check it still has the same geometry\n const same = entry?.geometry === geometry\n withTangents = withNormals && (withTangents || (same && !!entry?.attributes?.tangent))\n if (entry && same && entry.version === geometry.version && (!instances || entry.instanceVersion === instances.version) &&\n withTangents === !!entry.attributes?.tangent) return entry\n const layout = layoutOf(geometry, instances, withNormals, withTangents)\n if (entry && same && entry.layout === layout) {\n // the data changed but kept its shape (moving vertices, particles, instances): refill in place\n if (entry.version !== geometry.version) {\n const a = /** @type {Record<string, WebGLBuffer>} */ (entry.attributes)\n this.#refill(a.position, geometry.positions)\n if (withNormals) this.#refill(a.normal, geometry.normals)\n if (geometry.uvs) this.#refill(a.uv, geometry.uvs)\n if (geometry.uvs2) this.#refill(a.uv2, geometry.uvs2)\n if (geometry.colors) this.#refill(a.color, geometry.colors)\n if (withTangents) this.#refill(a.tangent, tangentsOf(geometry))\n if (geometry.indices) {\n // the element binding belongs to the vertex array, so bind that first\n this.gl.bindVertexArray(entry.vao)\n this.gl.bufferSubData(this.gl.ELEMENT_ARRAY_BUFFER, 0, geometry.indices)\n this.gl.bindVertexArray(null)\n }\n entry.version = geometry.version\n }\n if (instances && entry.instanceVersion !== instances.version) {\n this.#refill(entry.matrixBuffer, instances.instanceMatrices)\n if (instances.instanceColors) this.#refill(entry.colorBuffer, instances.instanceColors)\n entry.instanceVersion = instances.version\n }\n return entry\n }\n if (entry) {\n this.#free(entry)\n // given another geometry: the old one is no longer held here, and the new one is watched\n if (!same) {\n this.counts.geometries--\n this.#watch(geometry, key, cache)\n }\n } else this.#watch(geometry, key, cache)\n\n const gl = this.gl\n const vao = /** @type {WebGLVertexArrayObject} */ (gl.createVertexArray())\n gl.bindVertexArray(vao)\n /** @type {WebGLBuffer[]} */\n const buffers = []\n const attribute = (location, data, size, divisor = 0) => {\n const buffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW)\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl.FLOAT, false, 0, 0)\n if (divisor) gl.vertexAttribDivisor(location, divisor)\n buffers.push(buffer)\n return buffer\n }\n /** @type {Record<string, WebGLBuffer>} */\n const attributes = {}\n attributes.position = attribute(ATTRIBUTES.position, geometry.positions, 3)\n if (withNormals) attributes.normal = attribute(ATTRIBUTES.normal, geometry.normals, 3)\n if (geometry.uvs) attributes.uv = attribute(ATTRIBUTES.uv, geometry.uvs, 2)\n else gl.vertexAttrib2f(ATTRIBUTES.uv, 0, 0)\n if (geometry.uvs2) attributes.uv2 = attribute(ATTRIBUTES.uv2, geometry.uvs2, 2)\n if (geometry.colors) attributes.color = attribute(ATTRIBUTES.color, geometry.colors, 3)\n else gl.vertexAttrib3f(ATTRIBUTES.color, 1, 1, 1)\n if (withTangents) attributes.tangent = attribute(ATTRIBUTES.tangent, tangentsOf(geometry), 4)\n\n let matrixBuffer = null, colorBuffer = null\n if (instances) {\n matrixBuffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, matrixBuffer)\n gl.bufferData(gl.ARRAY_BUFFER, instances.instanceMatrices, gl.STATIC_DRAW)\n for (let i = 0; i < 4; i++) {\n const location = ATTRIBUTES.instanceMatrix + i\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, 4, gl.FLOAT, false, 64, i * 16)\n gl.vertexAttribDivisor(location, 1)\n }\n buffers.push(matrixBuffer)\n if (instances.instanceColors) colorBuffer = attribute(ATTRIBUTES.instanceColor, instances.instanceColors, 3, 1)\n else gl.vertexAttrib3f(ATTRIBUTES.instanceColor, 1, 1, 1)\n }\n\n let indexType = 0\n if (geometry.indices) {\n const buffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, geometry.indices, gl.STATIC_DRAW)\n buffers.push(buffer)\n indexType = geometry.indices instanceof Uint32Array ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT\n }\n gl.bindVertexArray(null)\n\n entry = { vao, buffers, count: geometry.elementCount, indexType, geometry, version: geometry.version,\n instanceVersion: instances?.version ?? 0, matrixBuffer, colorBuffer, attributes, layout }\n cache.set(key, entry)\n return entry\n }\n\n /**\n * Draw a mesh's triangles - instanced or not, indexed or not - with the program in use, as far as\n * its drawn count goes. Every pass that draws meshes draws them this way.\n * @param {Geometry} geometry @param {{ instanceMatrices: Float32Array, instanceColors: Float32Array | null, version: number, count: number } | null} instances\n * @param {boolean} [withTangents] for brushed metal\n * @returns {number} triangles drawn\n */\n drawTriangles(geometry, instances, withTangents = false) {\n const gl = this.gl\n const buffers = this.mesh(geometry, instances, true, withTangents)\n gl.bindVertexArray(buffers.vao)\n const elements = geometry.drawnCount - geometry.drawnCount % 3\n const count = instances ? instances.count : 1\n if (buffers.indexType) {\n if (instances) gl.drawElementsInstanced(gl.TRIANGLES, elements, buffers.indexType, 0, count)\n else gl.drawElements(gl.TRIANGLES, elements, buffers.indexType, 0)\n } else if (instances) gl.drawArraysInstanced(gl.TRIANGLES, 0, elements, count)\n else gl.drawArrays(gl.TRIANGLES, 0, elements)\n return elements / 3 * count\n }\n\n /** @param {WebGLBuffer | null | undefined} buffer @param {Float32Array} data */\n #refill(buffer, data) {\n const gl = this.gl\n gl.bindBuffer(gl.ARRAY_BUFFER, /** @type {WebGLBuffer} */ (buffer))\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, data)\n }\n\n /**\n * Vertex array for Lines: one instance per segment with its two endpoints (and colours) and where\n * it is along its chain, expanded to a screen-space quad - and arrowheads - in the vertex shader.\n * @param {Geometry} geometry\n * @returns {MeshBuffers}\n */\n lines(geometry) {\n this.#mark(geometry)\n let entry = this.#lines.get(geometry)\n if (entry && entry.version === geometry.version) return entry\n if (entry) this.#free(entry)\n else this.#watch(geometry, geometry, this.#lines)\n\n const gl = this.gl\n const p = geometry.positions, c = geometry.colors, idx = geometry.indices\n const segments = geometry.elementCount / 2\n const ends = new Float32Array(segments * 6)\n const colors = new Float32Array(segments * 6).fill(1)\n // chains: runs of segments each starting where the one before ended - a polyline. Dashes run\n // on along a chain, and arrowheads go at its ends\n const info = new Float32Array(segments * 3)\n for (let s = 0; s < segments; s++) {\n const i0 = idx ? idx[s * 2] : s * 2, i1 = idx ? idx[s * 2 + 1] : s * 2 + 1\n for (let k = 0; k < 3; k++) {\n ends[s * 6 + k] = p[i0 * 3 + k]\n ends[s * 6 + 3 + k] = p[i1 * 3 + k]\n if (c) {\n colors[s * 6 + k] = c[i0 * 3 + k]\n colors[s * 6 + 3 + k] = c[i1 * 3 + k]\n }\n }\n const o = s * 6, joined = s > 0 && ends[o - 3] === ends[o] && ends[o - 2] === ends[o + 1] && ends[o - 1] === ends[o + 2]\n if (joined) {\n info[s * 3] = info[s * 3 - 3] + Math.hypot(ends[o - 3] - ends[o - 6], ends[o - 2] - ends[o - 5], ends[o - 1] - ends[o - 4])\n info[s * 3 - 1] = 0\n } else info[s * 3 + 1] = 1\n info[s * 3 + 2] = 1\n }\n\n const vao = /** @type {WebGLVertexArrayObject} */ (gl.createVertexArray())\n gl.bindVertexArray(vao)\n /** @type {WebGLBuffer[]} */\n const buffers = []\n const interleavedPair = (data, first, second) => {\n const buffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW)\n for (const [location, offset] of [[first, 0], [second, 12]]) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, 3, gl.FLOAT, false, 24, offset)\n gl.vertexAttribDivisor(location, 1)\n }\n buffers.push(buffer)\n }\n interleavedPair(ends, ATTRIBUTES.segmentStart, ATTRIBUTES.segmentEnd)\n interleavedPair(colors, ATTRIBUTES.segmentColorStart, ATTRIBUTES.segmentColorEnd)\n const chains = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, chains)\n gl.bufferData(gl.ARRAY_BUFFER, info, gl.STATIC_DRAW)\n gl.enableVertexAttribArray(ATTRIBUTES.segmentInfo)\n gl.vertexAttribPointer(ATTRIBUTES.segmentInfo, 3, gl.FLOAT, false, 0, 0)\n gl.vertexAttribDivisor(ATTRIBUTES.segmentInfo, 1)\n buffers.push(chains)\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#cornerBuffer())\n gl.enableVertexAttribArray(ATTRIBUTES.corner)\n gl.vertexAttribPointer(ATTRIBUTES.corner, 2, gl.FLOAT, false, 0, 0)\n gl.bindVertexArray(null)\n\n entry = { vao, buffers, count: segments, indexType: 0, geometry, version: geometry.version, instanceVersion: 0 }\n this.#lines.set(geometry, entry)\n return entry\n }\n\n /**\n * The GL texture for a Texture - a 1x1 white placeholder until its image has loaded.\n * @param {Texture} texture\n * @returns {WebGLTexture}\n */\n texture(texture) {\n if (!texture.image) return this.#whiteTexture()\n this.#mark(texture)\n const gl = this.gl\n let entry = this.#textures.get(texture)\n if (entry && entry.version === texture.version) return entry.texture\n // a video with no frame yet: what it showed before, or white - and try again next frame\n if (isVideo(texture.image) && /** @type {HTMLVideoElement} */ (texture.image).readyState < 2) return entry?.texture ?? this.#whiteTexture()\n if (!entry) {\n entry = { texture: /** @type {WebGLTexture} */ (gl.createTexture()), version: -1, width: 0, height: 0, internal: 0 }\n this.#textures.set(texture, entry)\n this.counts.textures++\n texture.onDispose(() => this.#freeTexture(texture))\n }\n gl.activeTexture(gl.TEXTURE0 + UPLOAD_UNIT)\n gl.bindTexture(gl.TEXTURE_2D, entry.texture)\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY)\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false)\n const image = texture.image\n const data = 'data' in image ? /** @type {DataImage} */ (image) : null\n // raw pixels: bytes as usual, floats (HDR) as half floats, which filter everywhere; sRGB textures\n // are stored as sRGB so sampling returns linear values, filtered correctly\n const float = !!data && data.data instanceof Float32Array\n const internal = float ? gl.RGBA16F : texture.colorSpace === 'srgb' ? gl.SRGB8_ALPHA8 : gl.RGBA8\n const type = float ? gl.FLOAT : gl.UNSIGNED_BYTE\n const [width, height] = sizeOf(image)\n if (entry.version < 0 || entry.width !== width || entry.height !== height || entry.internal !== internal) {\n // new storage: the first upload, or the image changed size or kind\n if (data) gl.texImage2D(gl.TEXTURE_2D, 0, internal, width, height, 0, gl.RGBA, type, data.data)\n else gl.texImage2D(gl.TEXTURE_2D, 0, internal, gl.RGBA, type, /** @type {TexImageSource} */ (image))\n Object.assign(entry, { width, height, internal })\n } else {\n // the same storage, refilled: just the parts that changed, when the updates since said - a\n // canvas drawn on a little at a time - or the whole image (a video's next frame). A flipped\n // image's rows run the other way, so it goes whole\n let regions = texture.flipY ? null : texture.changedSince(entry.version)\n if (regions && regions.length > MOST_REGIONS) regions = byCell(regions, width, height)\n for (const r of regions ?? [{ x: 0, y: 0, width, height }]) {\n // inside the image: a region over its edge is cut there, one off it sends nothing\n const x = Math.max(0, r.x), y = Math.max(0, r.y)\n const w = Math.min(width, r.x + r.width) - x, h = Math.min(height, r.y + r.height) - y\n if (!(w > 0 && h > 0)) continue\n gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, x)\n gl.pixelStorei(gl.UNPACK_SKIP_ROWS, y)\n if (data) gl.pixelStorei(gl.UNPACK_ROW_LENGTH, width)\n gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, w, h, gl.RGBA, type, /** @type {any} */ (data ? data.data : image))\n }\n gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0)\n gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0)\n gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0)\n }\n const wrap = { repeat: gl.REPEAT, clamp: gl.CLAMP_TO_EDGE, mirror: gl.MIRRORED_REPEAT }[texture.wrap]\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap)\n const nearest = texture.filter === 'nearest'\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, nearest ? gl.NEAREST : gl.LINEAR)\n if (texture.mipmaps) {\n gl.generateMipmap(gl.TEXTURE_2D)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, nearest ? gl.NEAREST_MIPMAP_NEAREST : gl.LINEAR_MIPMAP_LINEAR)\n // sharp at glancing angles - as far as the GPU goes\n const aniso = this.#anisotropic()\n if (aniso && !nearest) gl.texParameterf(gl.TEXTURE_2D, aniso.ext.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, aniso.max))\n } else {\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, nearest ? gl.NEAREST : gl.LINEAR)\n }\n entry.version = texture.version\n return entry.texture\n }\n\n /**\n * A renderer is done with a scene: free the GPU copies of its geometry and textures that no\n * other renderer still draws.\n * @param {object} owner @param {Scene} scene\n */\n release(owner, scene) {\n /** @type {Set<object>} */\n const keys = new Set()\n const env = /** @type {any} */ (scene).environment, bg = /** @type {any} */ (scene).background\n if (env && typeof env === 'object') keys.add(env)\n if (bg && 'version' in bg) keys.add(bg)\n scene.traverse((n) => {\n const d = /** @type {any} */ (n)\n if (!d.isDrawable) return\n keys.add(d.geometry)\n if ('instanceMatrices' in d) keys.add(d)\n for (const [, t] of d.material.allTextures) keys.add(t)\n })\n for (const key of keys) {\n const users = this.#usedBy.get(key)\n if (!users?.delete(owner) || users.size) continue\n this.#usedBy.delete(key)\n for (const cache of [this.#triangles, this.#points, this.#lines, this.#sprites]) {\n const entry = cache.get(key)\n if (!entry) continue\n this.#free(entry)\n cache.delete(key)\n this.counts.geometries--\n }\n this.#freeTexture(/** @type {Texture} */ (key))\n }\n }\n\n /** @param {object} key */\n #mark(key) {\n if (!this.owner) return\n let users = this.#usedBy.get(key)\n if (!users) this.#usedBy.set(key, users = new Set())\n users.add(this.owner)\n }\n\n /**\n * Vertex array for points drawn as squares: one instance a point - its position, colour, size,\n * opacity, angle and index - over the corner strip lines use. Given a model-view matrix, the points\n * go back to front (furthest first) - re-sorted every call, as the camera may have moved; without\n * one, in their own order; with undefined, in whatever order they were last sent (picking, which\n * reads each point's index and doesn't mind).\n * @param {Geometry} geometry @param {ArrayLike<number> | null} [modelView]\n * @returns {MeshBuffers}\n */\n sprites(geometry, modelView) {\n this.#mark(geometry)\n const gl = this.gl\n let entry = this.#sprites.get(geometry)\n const sorting = !!modelView\n if (entry && entry.version === geometry.version && !sorting && (modelView === undefined || !entry.sorted)) return entry\n const n = geometry.drawnVertices, count = geometry.vertexCount\n if (!entry || entry.capacity < count) {\n if (entry) this.#free(entry)\n else this.#watch(geometry, geometry, this.#sprites)\n const vao = /** @type {WebGLVertexArrayObject} */ (gl.createVertexArray())\n gl.bindVertexArray(vao)\n const buffer = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, count * SPRITE_STRIDE * 4, gl.DYNAMIC_DRAW)\n for (const [location, size, offset] of SPRITE_LAYOUT) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl.FLOAT, false, SPRITE_STRIDE * 4, offset * 4)\n gl.vertexAttribDivisor(location, 1)\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#cornerBuffer())\n gl.enableVertexAttribArray(ATTRIBUTES.corner)\n gl.vertexAttribPointer(ATTRIBUTES.corner, 2, gl.FLOAT, false, 0, 0)\n gl.bindVertexArray(null)\n entry = { vao, buffers: [buffer], count: 0, indexType: 0, geometry, version: -1, instanceVersion: 0, capacity: count, sorted: false, data: new Float32Array(count * SPRITE_STRIDE) }\n this.#sprites.set(geometry, entry)\n }\n const order = sorting ? backToFront(geometry.positions, n, /** @type {ArrayLike<number>} */ (modelView)) : null\n const p = geometry.positions, c = geometry.colors, sizes = geometry.sizes, opacities = geometry.opacities, angles = geometry.angles\n const data = entry.data\n for (let j = 0; j < n; j++) {\n const i = order ? order[j] : j, o = j * SPRITE_STRIDE\n data[o] = p[i * 3]\n data[o + 1] = p[i * 3 + 1]\n data[o + 2] = p[i * 3 + 2]\n data[o + 3] = c ? c[i * 3] : 1\n data[o + 4] = c ? c[i * 3 + 1] : 1\n data[o + 5] = c ? c[i * 3 + 2] : 1\n data[o + 6] = sizes ? sizes[i] : 1\n data[o + 7] = opacities ? opacities[i] : 1\n data[o + 8] = angles ? angles[i] : 0\n data[o + 9] = i\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, entry.buffers[0])\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, data, 0, n * SPRITE_STRIDE)\n Object.assign(entry, { count: n, version: geometry.version, sorted: sorting })\n return entry\n }\n\n /** @param {Texture} texture */\n #freeTexture(texture) {\n const entry = this.#textures.get(texture)\n if (!entry) return\n this.gl.deleteTexture(entry.texture)\n this.#textures.delete(texture)\n this.counts.textures--\n }\n\n /** Forget everything - after a lost context, when every GL object is already gone. */\n reset() {\n this.#triangles = new WeakMap()\n this.#points = new WeakMap()\n this.#lines = new WeakMap()\n this.#sprites = new WeakMap()\n this.#textures = new WeakMap()\n this.#usedBy = new WeakMap()\n this.#white = null\n this.#corners = null\n // extensions go with a lost context; the next texture asks for this one again\n this.#aniso = undefined\n this.counts = { geometries: 0, textures: 0 }\n }\n\n // free GL objects for a geometry when it is disposed\n /** @param {Geometry} geometry @param {object} key @param {WeakMap<object, MeshBuffers>} cache */\n #watch(geometry, key, cache) {\n this.counts.geometries++\n geometry.onDispose(() => {\n const entry = cache.get(key)\n // gone, or the node has another geometry now\n if (!entry || entry.geometry !== geometry) return\n this.#free(entry)\n cache.delete(key)\n this.counts.geometries--\n })\n }\n\n /** @param {MeshBuffers} entry */\n #free(entry) {\n const gl = this.gl\n gl.deleteVertexArray(entry.vao)\n for (const b of entry.buffers) gl.deleteBuffer(b)\n }\n\n #whiteTexture() {\n if (this.#white) return this.#white\n const gl = this.gl\n this.#white = /** @type {WebGLTexture} */ (gl.createTexture())\n gl.activeTexture(gl.TEXTURE0 + UPLOAD_UNIT)\n gl.bindTexture(gl.TEXTURE_2D, this.#white)\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 255, 255]))\n return this.#white\n }\n\n #cornerBuffer() {\n if (this.#corners) return this.#corners\n const gl = this.gl\n this.#corners = /** @type {WebGLBuffer} */ (gl.createBuffer())\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#corners)\n gl.bufferData(gl.ARRAY_BUFFER, LINE_CORNERS, gl.STATIC_DRAW)\n return this.#corners\n }\n}\n\n/**\n * An image's size in pixels - a video's frames, an <img>'s own pixels rather than its size on the page.\n * @param {any} image @returns {[number, number]}\n */\nfunction sizeOf(image) {\n if (isVideo(image)) return [image.videoWidth, image.videoHeight]\n if ('naturalWidth' in image) return [image.naturalWidth, image.naturalHeight]\n return [image.width, image.height]\n}\n\n/**\n * Many regions as a few: those whose middles fall in the same cell of a GRID x GRID split of the\n * image, as one rectangle round them.\n * @param {import('../material/Texture.js').TextureRegion[]} regions @param {number} width @param {number} height\n */\nfunction byCell(regions, width, height) {\n /** @type {Map<number, number[]>} x0, y0, x1, y1 round each cell's regions */\n const cells = new Map()\n for (const r of regions) {\n const cx = Math.min(GRID - 1, Math.max(0, Math.floor((r.x + r.width / 2) / width * GRID)))\n const cy = Math.min(GRID - 1, Math.max(0, Math.floor((r.y + r.height / 2) / height * GRID)))\n const key = cy * GRID + cx, box = cells.get(key)\n if (!box) cells.set(key, [r.x, r.y, r.x + r.width, r.y + r.height])\n else {\n box[0] = Math.min(box[0], r.x)\n box[1] = Math.min(box[1], r.y)\n box[2] = Math.max(box[2], r.x + r.width)\n box[3] = Math.max(box[3], r.y + r.height)\n }\n }\n return [...cells.values()].map(([x0, y0, x1, y1]) => ({ x: x0, y: y0, width: x1 - x0, height: y1 - y0 }))\n}\n\n/**\n * The first n points' order furthest from the camera first: by their depth in view, given the\n * model-view matrix.\n * @param {Float32Array} p @param {number} n @param {ArrayLike<number>} m\n * @returns {Uint32Array}\n */\nfunction backToFront(p, n, m) {\n const depth = new Float32Array(n), order = new Uint32Array(n)\n for (let i = 0; i < n; i++) {\n // view space z: more negative is further away\n depth[i] = m[2] * p[i * 3] + m[6] * p[i * 3 + 1] + m[10] * p[i * 3 + 2] + m[14]\n order[i] = i\n }\n return order.sort((a, b) => depth[a] - depth[b])\n}\n","// A WebGL 2 context and everything made on it - programs, buffers, textures, the extra passes -\n// used by one renderer (its canvas's own context) or by many (one context shared by views that\n// draw into it and copy the picture to their own canvas, so a dashboard of 30 tiles stays well\n// under the browser's limit of about 16 live contexts).\nimport { fail } from '../validate.js'\nimport { Programs } from './programs.js'\nimport { Resources } from './resources.js'\n\n/** @import { Passes } from './passes.js' */\n/** @import { Picker } from './picking.js' */\n/** @import { Bloom } from './bloom.js' */\n/** @import { Scene } from '../scene/Scene.js' */\n\n/** @typedef {{ onReady: (() => void) | null }} ContextUser */\n\n/** @type {GLContext | null} */\nlet shared = null\n\nexport class GLContext {\n /** @type {HTMLCanvasElement | OffscreenCanvas} */ canvas\n /** @type {WebGL2RenderingContext} */ gl\n programs\n resources\n /** HDR environments, panorama backgrounds and shadows - loaded the first time a frame has one. @type {Passes | null} */\n passes = null\n /** GPU picking - loaded the first time something is picked. @type {Picker | null} */\n picker = null\n /** Bloom - loaded the first time a renderer asks for it. @type {Bloom | null} */\n bloom = null\n lost = false\n /** Counts frames across every renderer, so programs know when their per-frame uniforms are stale. */\n frame = 0\n /** @type {Set<ContextUser>} */ users = new Set()\n /** Shared by several renderers, each copying its picture out. */\n isShared\n #passesLoading = false\n #watchingCompiles = false\n #pickerLoading = false\n #bloomLoading = false\n /** @type {() => void} */ #removeListeners\n\n /**\n * @param {HTMLCanvasElement | OffscreenCanvas} canvas\n * @param {{ antialias?: boolean, shared?: boolean }} [options]\n */\n constructor(canvas, { antialias = true, shared: isShared = false } = {}) {\n this.canvas = canvas\n this.isShared = isShared\n // a canvas let go of moments ago keeps its context, rather than losing it\n const before = released.get(canvas)\n if (before) {\n clearTimeout(before.timer)\n released.delete(canvas)\n }\n // a stencil buffer for section planes' caps\n const gl = canvas.getContext('webgl2', { antialias, alpha: true, premultipliedAlpha: true, stencil: true, powerPreference: 'high-performance' })\n if (!gl) fail('WebGLRenderer', 'WebGL 2 is not available in this browser or on this device')\n this.gl = /** @type {WebGL2RenderingContext} */ (gl)\n this.programs = new Programs(this.gl)\n this.resources = new Resources(this.gl)\n\n // a lost context (GPU reset, too many contexts) is restored by the browser; every GPU object\n // is then recreated from the CPU-side data, and every renderer drawn again\n const lost = (/** @type {Event} */ e) => {\n e.preventDefault()\n this.lost = true\n }\n const restored = () => {\n this.lost = false\n this.programs.reset()\n this.resources.reset()\n this.passes?.reset()\n this.picker?.reset()\n this.bloom?.reset()\n for (const user of this.users) user.onReady?.()\n }\n canvas.addEventListener('webglcontextlost', lost)\n canvas.addEventListener('webglcontextrestored', restored)\n this.#removeListeners = () => {\n canvas.removeEventListener('webglcontextlost', lost)\n canvas.removeEventListener('webglcontextrestored', restored)\n }\n // ...or, let go of long enough ago that it was lost, asks for it back: drawing waits until the\n // browser restores it, then goes ahead as after any lost context\n if (before && gl.isContextLost()) {\n this.lost = true\n before.lose?.restoreContext()\n }\n }\n\n /** The page's shared context, made on first use. @returns {GLContext} */\n static shared() {\n if (!shared) {\n const canvas = typeof document !== 'undefined' ? document.createElement('canvas') : new OffscreenCanvas(1, 1)\n shared = new GLContext(canvas, { shared: true })\n }\n return shared\n }\n\n /**\n * Make the drawing buffer at least this big (a shared context draws each view into its corner).\n * It only grows, so views of different sizes don't reallocate it every frame.\n * @param {number} width @param {number} height\n */\n fit(width, height) {\n const c = this.canvas\n if (c.width >= width && c.height >= height) return\n // round up, so a canvas growing a pixel at a time doesn't reallocate each time\n c.width = Math.max(c.width, Math.ceil(width / 256) * 256)\n c.height = Math.max(c.height, Math.ceil(height / 256) * 256)\n }\n\n /**\n * The extra passes, once loaded; the first call that needs them starts loading them, and every\n * renderer on this context is told when they arrive.\n * @param {boolean} needed\n * @returns {Passes | null}\n */\n loadPasses(needed) {\n if (this.passes || !needed || this.#passesLoading) return this.passes\n this.#passesLoading = true\n import('./passes.js').then(({ Passes }) => {\n this.passes = new Passes(this.gl, this.programs, this.resources)\n for (const user of this.users) user.onReady?.()\n })\n return null\n }\n\n /**\n * Programs are compiling in the background: tell every renderer on this context when they are\n * all done, so it draws again with them.\n */\n whenCompiled() {\n if (this.#watchingCompiles) return\n this.#watchingCompiles = true\n const check = () => {\n if (this.lost || !this.users.size) {\n this.#watchingCompiles = false\n return\n }\n if (this.programs.compiling) {\n setTimeout(check, 4)\n return\n }\n this.#watchingCompiles = false\n for (const user of this.users) user.onReady?.()\n }\n setTimeout(check, 4)\n }\n\n /**\n * GPU picking, once loaded; the first call starts loading it, and every renderer on this context\n * is told when it arrives.\n * @returns {Picker | null}\n */\n loadPicker() {\n if (this.picker || this.#pickerLoading) return this.picker\n this.#pickerLoading = true\n import('./picking.js').then(({ Picker }) => {\n this.picker = new Picker(this.gl, this.programs, this.resources)\n for (const user of this.users) user.onReady?.()\n })\n return null\n }\n\n /**\n * Bloom, once loaded; the first call starts loading it, and every renderer on this context is\n * told when it arrives.\n * @returns {Bloom | null}\n */\n loadBloom() {\n if (this.bloom || this.#bloomLoading) return this.bloom\n this.#bloomLoading = true\n import('./bloom.js').then(({ Bloom }) => {\n this.bloom = new Bloom(this.gl, this.programs)\n for (const user of this.users) user.onReady?.()\n })\n return null\n }\n\n /**\n * A renderer is done with this context. Its scene's GPU copies are freed unless another renderer\n * still draws them; the last user frees everything, losing the context on purpose so the\n * browser reclaims it. A canvas's own context is lost a moment later rather than at once: a new\n * renderer on the same canvas before then - React's StrictMode mounts, disposes and mounts again\n * in one go - keeps the live context, as a canvas only ever has the one.\n * @param {ContextUser} user\n * @param {Scene} [scene] what the renderer drew\n */\n release(user, scene) {\n this.users.delete(user)\n if (scene) this.resources.release(user, scene)\n if (this.users.size) return\n this.programs.dispose()\n this.resources.reset()\n this.passes?.reset()\n this.bloom?.dispose()\n this.#removeListeners()\n const lose = this.gl.getExtension('WEBGL_lose_context')\n if (this === shared) {\n lose?.loseContext()\n shared = null\n return\n }\n released.set(this.canvas, { lose, timer: setTimeout(() => lose?.loseContext()) })\n }\n}\n\n/**\n * Canvases whose last renderer let go of them, with the timer that will lose the context and the\n * extension that does it (kept, as a lost context gives out no extensions to restore it with).\n * @type {WeakMap<object, { lose: any, timer: ReturnType<typeof setTimeout> }>}\n */\nconst released = new WeakMap()\n","import * as mat3 from '../math/mat3.js'\nimport * as mat4 from '../math/mat4.js'\nimport { Geometry } from '../geometry/Geometry.js'\nimport { Material } from '../material/Material.js'\nimport { CLIP_ONLY_FRAGMENT, MESH_VERTEX } from './shaders.js'\nimport { hookFailed, hookFor, setHookUniforms } from './hooks.js'\nimport { collect } from '../frame.js'\nimport { checkNumber, checkOneOf, checkOptions, checkRange, describe, fail, warnOnce } from '../validate.js'\nimport { GLContext } from './context.js'\nimport { uvMatrix } from './resources.js'\n\n/** @import { FrameDescription, DrawItem, FrameLight, FrameCap } from '../frame.js' */\n/** @import { Scene } from '../scene/Scene.js' */\n/** @import { Camera } from '../scene/cameras.js' */\n/** @import { Texture } from '../material/Texture.js' */\n/** @import { Environment } from './passes.js' */\n/** @import { GPUHit } from './picking.js' */\n\n/** @typedef {'aces' | 'neutral' | 'none'} ToneMapping */\n\n/**\n * Glow round the bright parts of the picture - emissive materials, additive points and lines, lit\n * highlights - as light spills round them through a lens.\n * @typedef {object} BloomOptions\n * @property {number} [strength] how much glow is added (default 1)\n * @property {number} [radius] 0 - 1: how far it spreads (default 0.6)\n * @property {number} [threshold] 0 - 1: how bright a colour has to be to glow (default 0.6)\n */\n\n/**\n * @typedef {object} WebGLRendererOptions\n * @property {HTMLCanvasElement | OffscreenCanvas} canvas\n * @property {boolean} [shared] draw with the page's one shared WebGL context and copy the picture to\n * this canvas, instead of giving the canvas a context of its own - for pages with many views\n * (browsers allow about 16 live contexts). The View decides this; see its 'context' option.\n * @property {boolean} [antialias] multisampling (default true; a shared context always has it)\n * @property {boolean} [outlineAntialias] soft-edged outlines with round corners (default: as antialias)\n * @property {ToneMapping} [toneMapping] how lit colours are mapped to the screen: 'neutral' keeps colours\n * true (Khronos PBR Neutral, the default), 'aces' is filmic, 'none' clips\n * @property {number} [exposure] (default 1)\n * @property {number} [pixelRatio] drawing buffer pixels per CSS pixel (default 1; View sets it)\n * @property {boolean | BloomOptions} [bloom] glow round bright parts (default off); loads its code the first time\n */\n\nconst OPTIONS = ['canvas', 'shared', 'antialias', 'outlineAntialias', 'toneMapping', 'exposure', 'pixelRatio', 'bloom']\nconst BLOOM = { strength: 1, radius: 0.6, threshold: 0.6 }\n/** What bloom: { ... } takes, and hints for names people reach for instead. */\nexport const BLOOM_OPTIONS = Object.keys(BLOOM)\nexport const BLOOM_HINTS = { intensity: \"use 'strength'\", amount: \"use 'strength'\", size: \"use 'radius'\", blur: \"use 'radius'\" }\nconst HINTS = { alpha: 'the canvas is always transparent where the scene has no background' }\n\n/**\n * Bloom options as settings: true for the defaults, false or null for none.\n * @param {string} owner @param {boolean | BloomOptions | null | undefined} value\n * @returns {Required<BloomOptions> | null}\n */\nexport function bloomSettings(owner, value) {\n if (value === undefined || value === null || value === false) return null\n if (value === true) return { ...BLOOM }\n if (typeof value !== 'object') fail(owner, `bloom is true, false or { strength, radius, threshold }, got ${describe(value)}`)\n checkOptions(`${owner} bloom`, value, BLOOM_OPTIONS, BLOOM_HINTS)\n const settings = { ...BLOOM }\n for (const key of /** @type {(keyof BloomOptions)[]} */ (Object.keys(BLOOM))) {\n if (value[key] !== undefined) settings[key] = checkNumber(`${owner} bloom`, key, value[key])\n }\n return settings\n}\nconst TONE_MAPPING = { none: 0, aces: 1, neutral: 2 }\n// material maps and the shader feature each one switches on (all but emissive need lighting)\n/** @type {import('./passes.js').ShadowMap[]} */\nconst NO_SHADOWS = []\nconst MAP_DEFINES = { roughnessMap: 'ROUGHNESS_MAP', metalnessMap: 'METALNESS_MAP', normalMap: 'NORMAL_MAP', bumpMap: 'BUMP_MAP', aoMap: 'AO_MAP', lightMap: 'LIGHT_MAP' }\n// every map a mesh can sample - triplanar projection is only worth its varyings when there is one\nconst MAP_SLOTS = ['map', 'emissiveMap', ...Object.keys(MAP_DEFINES)]\nconst MAP_UNIFORMS = { matcap: 'uMatcap', map: 'uMap', roughnessMap: 'uRoughnessMap', metalnessMap: 'uMetalnessMap', normalMap: 'uNormalMap', bumpMap: 'uBumpMap', aoMap: 'uAoMap', emissiveMap: 'uEmissiveMap', lightMap: 'uLightMap' }\n// counting a cap's faces into the stencil: the solids' surfaces, colour and depth left alone\nconst CLIP_MASK = /** @type {[string, string]} */ ([MESH_VERTEX, CLIP_ONLY_FRAGMENT])\n// a cap: a square on the plane, two units across, facing +Y until it is placed\nconst CAP_SQUARE = new Geometry({\n positions: [-1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1], normals: [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0],\n uvs: [0, 0, 1, 0, 1, 1, 0, 1], indices: [0, 2, 1, 0, 3, 2],\n})\n// what a cap is drawn as - a plain node, never in a scene\nconst CAP_NODE = /** @type {any} */ ({ drawMode: 'triangles', receiveShadow: true, castShadow: false, renderOrder: 0 })\n\n/**\n * Draws a scene with WebGL 2. The View creates one; use it directly to drive your own loop:\n *\n * const renderer = new WebGLRenderer({ canvas })\n * renderer.setSize(canvas.clientWidth, canvas.clientHeight, devicePixelRatio)\n * scene.update(dt, t)\n * renderer.render(scene, camera)\n */\nexport class WebGLRenderer {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n /** The canvas the picture ends up on. @type {HTMLCanvasElement | OffscreenCanvas} */ canvas\n /** @type {ToneMapping} */ toneMapping = 'neutral'\n exposure = 1\n pixelRatio = 1\n /** Outlines with soft edges and round corners, or hard pixel steps; takes effect on the next frame. */\n outlineAntialias = true\n /** @type {Required<BloomOptions> | null} */ #bloom = null\n /** Counts from the last frame and the GPU caches. */\n info = { drawCalls: 0, triangles: 0, programs: 0, geometries: 0, textures: 0, compiling: 0 }\n /**\n * Called when something the last frame couldn't draw yet is ready - the code for HDR\n * environments, backgrounds and shadows, which loads the first time a scene has one. The View\n * redraws then. @type {(() => void) | null}\n */\n onReady = null\n\n /** The context drawn with: the canvas's own, or the page's shared one. @type {GLContext} */\n #gpu\n /** With a shared context: the canvas's 2D context, which the picture is copied into. @type {CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null} */\n #copy = null\n /** This frame's prefiltered environment, when it is an HDR image. @type {Environment | null} */ #environment = null\n /** This frame's shadows - directional, spot, point - for the meshes that receive them. @type {import('./passes.js').ShadowMap[]} */ #shadows = []\n /** @type {Float32Array} */ #normalMatrix = new Float32Array(9)\n /** Model-view for sorting points back to front. */\n #modelView = new Float32Array(16)\n /** @type {Record<string, any>} */ #lights = {}\n /** This frame waits for shaders to compile rather than leaving things out. */\n #wait = false\n /** This frame's light counts and environment, compiled into the lit programs. @type {string[]} */ #lightDefines = []\n #studio = false\n /** A cap's material, by colour, so each colour compiles and uploads once. @type {Map<number, Material>} */ #capMaterials = new Map()\n\n /** @param {WebGLRendererOptions} options */\n constructor(options) {\n checkOptions('WebGLRenderer', options, OPTIONS, HINTS)\n if (!options?.canvas) fail('WebGLRenderer', \"'canvas' is required\")\n this.canvas = options.canvas\n if (options.toneMapping !== undefined) this.toneMapping = checkOneOf('WebGLRenderer', 'toneMapping', options.toneMapping, ['aces', 'neutral', 'none'])\n if (options.exposure !== undefined) this.exposure = checkRange('WebGLRenderer', 'exposure', options.exposure, 0)\n if (options.pixelRatio !== undefined) this.pixelRatio = checkRange('WebGLRenderer', 'pixelRatio', options.pixelRatio, 0, Infinity, { above: true })\n this.#bloom = bloomSettings('WebGLRenderer', options.bloom)\n // outlines follow the picture's antialiasing unless told otherwise (a shared context always has it)\n this.outlineAntialias = options.outlineAntialias !== undefined ? !!options.outlineAntialias : options.shared || options.antialias !== false\n\n if (options.shared) {\n this.#gpu = GLContext.shared()\n const copy = this.canvas.getContext('2d')\n if (!copy) fail('WebGLRenderer', \"a shared renderer's canvas needs a 2D context - give it a canvas that has no WebGL context yet\")\n this.#copy = /** @type {CanvasRenderingContext2D} */ (copy)\n } else {\n this.#gpu = new GLContext(this.canvas, { antialias: options.antialias })\n }\n this.#gpu.users.add(this)\n }\n\n /**\n * Glow round the bright parts of the picture: null for none, or its settings. Set true, false or\n * { strength, radius, threshold }; change its numbers in place to tune it.\n * @returns {Required<BloomOptions> | null}\n */\n get bloom() {\n return this.#bloom\n }\n\n /** @param {boolean | BloomOptions | null} value */\n set bloom(value) {\n this.#bloom = bloomSettings('WebGLRenderer', value)\n }\n\n /** The WebGL 2 context drawn with - shared with other renderers when `shared` is set. @returns {WebGL2RenderingContext} */\n get gl() {\n return this.#gpu.gl\n }\n\n /** Drawing with the page's shared context? */\n get shared() {\n return this.#gpu.isShared\n }\n\n /**\n * Size the drawing buffer for a CSS size and pixel ratio. (The canvas's CSS size is left alone.)\n * @param {number} width CSS pixels\n * @param {number} height CSS pixels\n * @param {number} [pixelRatio]\n */\n setSize(width, height, pixelRatio = this.pixelRatio) {\n this.pixelRatio = pixelRatio\n this.canvas.width = Math.max(1, Math.round(width * pixelRatio))\n this.canvas.height = Math.max(1, Math.round(height * pixelRatio))\n }\n\n /**\n * Bring world matrices up to date, collect what's visible and draw it. Doesn't run update\n * handlers - the loop owner calls scene.update(dt, t) once per frame.\n * @param {Scene} scene\n * @param {Camera} camera\n * @returns {FrameDescription}\n */\n render(scene, camera) {\n scene.updateWorldTree()\n return this.renderFrame(collect(scene, camera))\n }\n\n /** @internal\n * Draw a frame. Shaders compile in the background where the browser allows, and what is still\n * compiling is left out (info.compiling counts it; onReady fires when it's done) - unless `wait`\n * is set, for a frame that must be complete, such as an image export.\n * @param {FrameDescription} frame\n * @param {{ wait?: boolean }} [options]\n * @returns {FrameDescription}\n */\n renderFrame(frame, { wait = false } = {}) {\n const gpu = this.#gpu\n if (gpu.lost) return frame\n const gl = gpu.gl\n gpu.frame++\n // what this frame touches counts as this renderer's, for freeing a shared context's copies\n gpu.resources.owner = this\n this.#wait = wait\n this.info.drawCalls = 0\n this.info.triangles = 0\n this.info.compiling = 0\n const width = this.canvas.width, height = this.canvas.height\n // a shared context draws into the bottom-left corner of its buffer, then copies that out\n if (gpu.isShared) gpu.fit(width, height)\n\n const env = frame.environment\n const bg = frame.background\n const passes = gpu.loadPasses(!!frame.shadow || frame.spotShadows.length > 0 || !!frame.pointShadow || frame.outlines.length > 0 || (typeof env === 'object' && !!env.image) || (!!bg && !('getHex' in bg) && !!bg.image))\n // shader hooks that read the clock read it in the shadow maps and outlines too\n if (passes) {\n passes.time = frame.time ?? 0\n passes.cameraPosition = frame.camera.position\n }\n this.#environment = passes && typeof env === 'object' ? passes.environment(env) : null\n if (passes && typeof env === 'object' && env.image && !this.#environment) {\n warnOnce(env, env.isHDR ? \"this device can't render to float textures, which HDR environments need - lighting without it\"\n : \"'environment' needs an HDR image (a .hdr file) - lighting without it\")\n }\n // an HDR background is prefiltered here too, before the scene's target is bound: prefiltering\n // draws into targets of its own and leaves the framebuffer and viewport behind it\n if (passes && bg && !('getHex' in bg) && bg.isHDR) passes.environment(bg)\n // the lights' views first, each into its own depth texture\n this.#shadows = !passes ? [] : [\n frame.shadow && passes.shadowMap(frame.shadow),\n frame.spotShadows.length > 0 && passes.spotShadowMaps(frame.spotShadows),\n frame.pointShadow && passes.pointShadowMap(frame.pointShadow),\n ].filter((s) => !!s)\n // outlines' mask, drawn before the scene, so the scene's own target need not be left\n const outline = passes && frame.outlines.length ? passes.outlineMask(frame.outlines, frame, width, height, this.pixelRatio, this.outlineAntialias) : null\n\n // with bloom, the scene is drawn into a buffer of its own first (drawn plainly while its code loads)\n const bloom = this.#bloom ? gpu.loadBloom() : null\n // its buffers are big: once no view on this context wants bloom, they go (and come back if one does)\n if (!bloom && gpu.bloom && ![...gpu.users].some((u) => /** @type {any} */ (u).bloom)) gpu.bloom.dispose()\n if (bloom) bloom.begin(width, height)\n else {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null)\n gl.viewport(0, 0, width, height)\n }\n if (bg && 'getHex' in bg) {\n const [r, g, b] = bg.toSRGB()\n gl.clearColor(r, g, b, 1)\n } else {\n gl.clearColor(0, 0, 0, 0)\n }\n gl.depthMask(true)\n // clear only this view's corner of a shared buffer\n gl.enable(gl.SCISSOR_TEST)\n gl.scissor(0, 0, width, height)\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)\n gl.disable(gl.SCISSOR_TEST)\n if (passes && bg && !('getHex' in bg) && bg.image) {\n passes.background(frame, /** @type {Texture} */ (bg), { exposure: this.exposure, toneMapping: TONE_MAPPING[this.toneMapping] })\n }\n gl.enable(gl.DEPTH_TEST)\n gl.depthFunc(gl.LEQUAL)\n\n this.#gatherLights(frame)\n\n gl.disable(gl.BLEND)\n for (const item of frame.opaque) this.#draw(item, frame, false)\n // section planes' caps fill the cut faces of the solids just drawn, before anything see-through\n for (const cap of frame.caps) this.#cap(cap, frame, width, height)\n gl.enable(gl.BLEND)\n for (const item of frame.transparent) this.#draw(item, frame, true)\n // outlines over everything\n if (outline && passes) passes.outlineComposite(outline)\n gl.depthMask(true)\n gl.disable(gl.BLEND)\n gl.bindVertexArray(null)\n if (bloom && this.#bloom) bloom.end(this.#bloom)\n\n if (this.info.compiling) gpu.whenCompiled()\n if (this.#copy) {\n // the picture is the buffer's bottom-left corner; as an image, y runs down from the top\n const copy = this.#copy, source = gpu.canvas\n copy.globalCompositeOperation = 'copy'\n copy.drawImage(source, 0, source.height - height, width, height, 0, 0, width, height)\n }\n\n this.info.programs = gpu.programs.count\n this.info.geometries = gpu.resources.counts.geometries\n this.info.textures = gpu.resources.counts.textures\n return frame\n }\n\n /**\n * What is drawn at a pixel of a frame this renderer drew, found on the GPU: the drawable, which\n * instance, point or segment, and where. Undefined while the picking code loads (onReady fires\n * when it has) or while the context is lost - pick on the CPU meanwhile.\n * @param {FrameDescription} frame\n * @param {number} x @param {number} y CSS pixels from the canvas's top left\n * @returns {GPUHit | null | undefined}\n */\n pick(frame, x, y) {\n const gpu = this.#gpu\n if (gpu.lost) return undefined\n const picker = gpu.loadPicker()\n if (!picker) return undefined\n gpu.resources.owner = this\n const r = this.pixelRatio\n return picker.pick(frame, x * r, y * r, this.canvas.width, this.canvas.height, r)\n }\n\n /** @internal\n * pick() without waiting for the GPU: resolves once it has finished. Undefined while the picking\n * code loads; null while an earlier request is still out.\n * @param {FrameDescription} frame\n * @param {number} x @param {number} y CSS pixels from the canvas's top left\n * @returns {Promise<GPUHit | null> | null | undefined}\n */\n pickAsync(frame, x, y) {\n const gpu = this.#gpu\n if (gpu.lost) return undefined\n const picker = gpu.loadPicker()\n if (!picker) return undefined\n gpu.resources.owner = this\n const r = this.pixelRatio\n return picker.pickAsync(frame, x * r, y * r, this.canvas.width, this.canvas.height, r)\n }\n\n /**\n * Free the GPU resources this renderer made. With its own context that is everything (the\n * context is released); with the shared one, the copies of what `scene` draws that no other\n * renderer still uses - and everything, once the last renderer goes.\n * @param {Scene} [scene] what it drew\n */\n dispose(scene) {\n this.#gpu.release(this, scene)\n }\n\n /** @param {FrameDescription} frame */\n #gatherLights(frame) {\n const ambient = [0, 0, 0], sky = [0, 0, 0], ground = [0, 0, 0]\n // sized to the lights there are: the programs are compiled for exactly that many\n const directional = frame.lights.filter((l) => l.kind === 'directional').length\n const punctual = frame.lights.filter((l) => l.kind === 'point' || l.kind === 'spot').length\n const dirDirection = new Float32Array(directional * 3), dirColor = new Float32Array(directional * 3)\n const pos = new Float32Array(punctual * 3), color = new Float32Array(punctual * 3)\n const range = new Float32Array(punctual), direction = new Float32Array(punctual * 3), shadowTile = new Float32Array(punctual).fill(-1)\n const cone = new Float32Array(punctual * 2)\n let dirCount = 0, punctualCount = 0, pointShadowIndex = -1\n /** @param {number[] | Float32Array} out @param {number} offset @param {FrameLight} l @param {ArrayLike<number>} [c] */\n const addColor = (out, offset, l, c = l.color) => {\n out[offset] += c[0] * l.intensity\n out[offset + 1] += c[1] * l.intensity\n out[offset + 2] += c[2] * l.intensity\n }\n for (const l of frame.lights) {\n if (l.kind === 'ambient') addColor(ambient, 0, l)\n else if (l.kind === 'hemisphere') {\n addColor(sky, 0, l)\n addColor(ground, 0, l, l.ground)\n } else if (l.kind === 'directional') {\n const d = /** @type {ArrayLike<number>} */ (l.direction)\n // the shader wants the direction towards the light\n dirDirection.set([-d[0], -d[1], -d[2]], dirCount * 3)\n addColor(dirColor, dirCount * 3, l)\n dirCount++\n } else {\n const i = punctualCount++\n pos.set(/** @type {ArrayLike<number>} */ (l.position), i * 3)\n addColor(color, i * 3, l)\n range[i] = l.range ?? 0\n if (l === frame.pointShadow?.light) pointShadowIndex = i\n if (l.kind === 'spot') {\n direction.set(/** @type {ArrayLike<number>} */ (l.direction), i * 3)\n shadowTile[i] = l.shadowTile ?? -1\n const angle = /** @type {number} */ (l.angle)\n cone[i * 2] = Math.cos(angle)\n cone[i * 2 + 1] = Math.cos(angle * (1 - (l.penumbra ?? 0)))\n } else {\n // a cone wider than any angle: smoothstep(-2, -1, cos) is always 1\n cone[i * 2] = -2\n cone[i * 2 + 1] = -1\n }\n }\n }\n this.#lightDefines = [`NUM_DIRECTIONAL ${dirCount}`, `NUM_PUNCTUAL ${punctualCount}`]\n this.#studio = frame.environment === 'studio'\n this.#lights = {\n uAmbient: ambient, uHemisphereSky: sky, uHemisphereGround: ground,\n uDirectionalDirection: dirDirection, uDirectionalColor: dirColor,\n uPunctualPosition: pos, uPunctualColor: color, uPunctualRange: range,\n uPunctualDirection: direction, uPunctualCone: cone, uPunctualShadow: shadowTile, uPointShadowIndex: pointShadowIndex,\n }\n }\n\n /** @param {DrawItem} item @param {FrameDescription} frame @param {boolean} transparent */\n #draw(item, frame, transparent) {\n const gl = this.gl\n const { node, geometry, material, worldMatrix, instances } = item\n const mode = /** @type {any} */ (node).drawMode\n const kind = mode === 'points' ? 'points' : mode === 'lines' ? 'lines' : 'mesh'\n const receives = kind === 'mesh' && node.receiveShadow && !material.unlit\n const shadows = receives ? this.#shadows : NO_SHADOWS\n\n const clip = kind === 'mesh' ? item.clip : null\n const defines = this.#defines(kind, material, geometry.colors !== null, !!instances, geometry.uvs2 !== null)\n if (kind === 'points' && /** @type {any} */ (node).drawsSprites) defines.push('SPRITES')\n for (const shadow of shadows) defines.push(shadow.define)\n const fog = material.fog ? frame.fog : null\n if (fog) {\n defines.push('FOG')\n if (fog.linear) defines.push('FOG_LINEAR')\n if (material.blending === 'additive') defines.push('FOG_ADD')\n else if (material.blending === 'multiply') defines.push('FOG_MULTIPLY')\n }\n if (clip) defines.push('CLIP')\n // a material's own GLSL, spliced into this program\n const hook = hookFor(material)\n if (hook) defines.push(...hook.defines)\n const programs = this.#gpu.programs\n const program = programs.get(kind, defines, undefined, hook?.source)\n if (!programs.isReady(program)) {\n if (!this.#wait) {\n // still compiling: drawn once it's done, rather than holding up everything else\n this.info.compiling++\n return\n }\n programs.ready(kind, defines, undefined, hook?.source)\n }\n if (program.failed) {\n // reported once; drawn without the hooks from the next frame\n hookFailed(material, /** @type {import('./hooks.js').Hook} */ (hook), program.failed)\n // counted as still compiling, so the View draws again - with the material's plain program\n this.info.compiling++\n return\n }\n gl.useProgram(program.program)\n\n // per-frame values, once per program per frame\n if (program.frame !== this.#gpu.frame) {\n program.frame = this.#gpu.frame\n program.set('uView', frame.camera.view)\n program.set('uProjection', frame.camera.projection)\n program.set('uViewProjection', frame.camera.viewProjection)\n program.set('uCameraPosition', frame.camera.position)\n program.set('uExposure', this.exposure)\n program.set('uToneMapping', TONE_MAPPING[this.toneMapping])\n program.set('uResolution', [this.canvas.width, this.canvas.height])\n program.set('uNear', frame.camera.near)\n program.set('uScale', frame.camera.projection[5] * this.canvas.height / 2)\n if (kind === 'mesh' && !material.unlit) {\n for (const [name, value] of Object.entries(this.#lights)) program.set(name, value)\n const env = this.#environment\n if (env) {\n program.set('uEnvMaxLod', env.maxLod)\n program.set('uEnvSH', env.sh)\n program.set('uEnvIntensity', frame.environmentIntensity)\n }\n for (const shadow of shadows) for (const [name, value] of Object.entries(shadow.uniforms)) program.set(name, value)\n }\n }\n // the frame's own textures are bound every draw, not once a frame: other programs drawn in\n // between bind their maps to the same texture units, and a shadow sampler left reading an\n // ordinary texture makes the draw fail\n if (kind === 'mesh' && !material.unlit) {\n if (this.#environment) program.set('uEnvMap', this.#environment.prefiltered)\n for (const shadow of shadows) program.set(shadow.sampler, shadow.texture)\n }\n\n program.set('uModel', worldMatrix)\n const hl = frame.highlight\n if (hl && (hl.nodes ? hl.nodes.has(node) : hl.node === node)) {\n program.set('uHighlightIndex', hl.index ?? -1)\n program.set('uHighlight', [hl.color[0], hl.color[1], hl.color[2], hl.amount])\n } else {\n program.set('uHighlightIndex', -2)\n }\n program.set('uColor', material.color)\n program.set('uOpacity', material.opacity)\n if (hook) setHookUniforms(program, material, frame.time ?? 0, frame.camera.position, (t) => this.#gpu.resources.texture(t))\n if (fog) {\n program.set('uFogColor', fog.color)\n program.set('uFogRange', [fog.near, fog.far])\n program.set('uFogDensity', fog.density)\n }\n if (clip) program.set('uClipPlane', clip.plane)\n const e = material.emissive, k = material.emissiveIntensity\n program.set('uEmissive', [e[0] * k, e[1] * k, e[2] * k])\n program.set('uRoughness', material.roughness)\n program.set('uMetalness', material.metalness)\n program.set('uNormalScale', material.normalScale)\n if (material.bumpMap) program.set('uBumpScale', material.bumpScale)\n if (material.triplanar > 0) program.set('uTriplanar', material.triplanar)\n program.set('uAoMapIntensity', material.aoMapIntensity)\n if (material.transmission > 0) program.set('uTransmission', material.transmission)\n if (material.clearcoat > 0) {\n program.set('uClearcoat', material.clearcoat)\n program.set('uClearcoatRoughness', material.clearcoatRoughness)\n }\n // a non-metal's reflectance face on, from its ior and specular settings, and at grazing angles\n const ior = (material.ior - 1) / (material.ior + 1), sc = material.specularColor, si = material.specularIntensity\n program.set('uSpecular', [Math.min(ior * ior * sc[0], 1) * si, Math.min(ior * ior * sc[1], 1) * si, Math.min(ior * ior * sc[2], 1) * si, si])\n if (material.sheen > 0) {\n const c = material.sheenColor, k = material.sheen\n program.set('uSheenColor', [c[0] * k, c[1] * k, c[2] * k])\n program.set('uSheenRoughness', material.sheenRoughness)\n }\n if (material.anisotropy > 0) {\n program.set('uAnisotropy', material.anisotropy)\n program.set('uAnisotropyDirection', [Math.cos(material.anisotropyRotation), Math.sin(material.anisotropyRotation)])\n }\n if (material.translucency > 0) {\n const c = material.translucencyColor, k = material.translucency\n program.set('uTranslucency', [c[0] * k, c[1] * k, c[2] * k, k])\n }\n if (material.toon > 0) program.set('uToon', Math.max(2, Math.round(material.toon)))\n program.set('uAlphaTest', material.alphaTest)\n /** @type {[string, Texture][]} */\n const maps = kind === 'mesh' ? material.textures : material.map ? [['map', material.map]] : []\n // GL textures first (uploads use a unit of their own), then bind them to the samplers\n const bound = maps.map(([slot, texture]) => [MAP_UNIFORMS[slot], this.#gpu.resources.texture(texture)])\n for (const [name, texture] of bound) program.set(name, texture)\n // each map's own repeat, rotation and offset (a matcap takes no UVs)\n for (const [slot, texture] of maps) if (slot !== 'matcap') program.set(`${MAP_UNIFORMS[slot]}Uv`, uvMatrix(texture))\n if (material.lightMap) program.set('uLightMapIntensity', material.lightMapIntensity)\n program.set('uEnvStrength', material.environmentIntensity)\n\n // render state\n gl.depthMask(!transparent && material.depthWrite)\n if (material.depthTest) gl.enable(gl.DEPTH_TEST)\n else gl.disable(gl.DEPTH_TEST)\n if (transparent) {\n // output is premultiplied, so 'normal' is ONE / ONE_MINUS_SRC_ALPHA; 'multiply' scales what is\n // behind by the colour, as much as the opacity says: dst * (colour * opacity + 1 - opacity)\n if (material.blending === 'additive') gl.blendFunc(gl.ONE, gl.ONE)\n else if (material.blending === 'multiply') gl.blendFunc(gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA)\n else gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n }\n\n if (kind === 'lines') {\n gl.disable(gl.CULL_FACE)\n program.set('uWidth', material.width * this.pixelRatio)\n const arrows = /** @type {any} */ (node).arrowBits ?? 0\n program.set('uArrows', arrows)\n program.set('uArrowSize', /** @type {any} */ (node).arrowPixels?.(material.width) * this.pixelRatio || 0)\n if (material.dash > 0) {\n program.set('uDash', material.dash)\n program.set('uGap', material.gap || material.dash)\n program.set('uDashOffset', material.dashOffset)\n }\n const buffers = this.#gpu.resources.lines(geometry)\n gl.bindVertexArray(buffers.vao)\n // a quad a segment, and two arrowheads where there are any\n gl.drawArraysInstanced(gl.TRIANGLES, 0, arrows ? 12 : 6, Math.min(buffers.count, Math.floor(geometry.drawnCount / 2)))\n this.info.drawCalls++\n return\n }\n\n if (kind === 'points') {\n gl.disable(gl.CULL_FACE)\n program.set('uSize', material.sizeAttenuation ? material.size : material.size * this.pixelRatio)\n // round points are solid, but their edges are soft: blended over what is behind even in the\n // opaque pass, or the edge fades to black - a dark ring round every dot\n const round = !transparent && !material.map\n if (round) {\n gl.enable(gl.BLEND)\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n }\n if (/** @type {any} */ (node).drawsSprites) {\n // each point a square, any size and turned - drawn back to front when the points ask, for\n // smoke and other soft things that hide what is behind them\n program.set('uResolution', [this.canvas.width, this.canvas.height])\n const modelView = /** @type {any} */ (node).sort ? mat4.multiply(this.#modelView, frame.camera.view, worldMatrix) : null\n const buffers = this.#gpu.resources.sprites(geometry, modelView)\n gl.bindVertexArray(buffers.vao)\n gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, buffers.count)\n } else {\n const buffers = this.#gpu.resources.mesh(geometry, null, false)\n gl.bindVertexArray(buffers.vao)\n gl.drawArrays(gl.POINTS, 0, geometry.drawnVertices)\n }\n if (round) gl.disable(gl.BLEND)\n this.info.drawCalls++\n return\n }\n\n // triangles\n if (!mat3.normalFromMat4(this.#normalMatrix, worldMatrix)) mat3.identity(this.#normalMatrix)\n program.set('uNormalMatrix', this.#normalMatrix)\n // a mirroring transform (negative scale) reverses the winding - which also says which side is\n // the back, for double-sided materials\n gl.frontFace(mat4.determinant(worldMatrix) < 0 ? gl.CW : gl.CCW)\n if (material.doubleSided) {\n gl.disable(gl.CULL_FACE)\n } else {\n gl.enable(gl.CULL_FACE)\n gl.cullFace(gl.BACK)\n }\n // surfaces sit a hair behind their own depth, so a line lying on one - an edge, a seam, a\n // drawing's outline - shows whole rather than fighting it pixel by pixel\n gl.enable(gl.POLYGON_OFFSET_FILL)\n gl.polygonOffset(1, 2)\n this.info.triangles += this.#gpu.resources.drawTriangles(geometry, instances, material.anisotropy > 0 && !material.unlit)\n gl.disable(gl.POLYGON_OFFSET_FILL)\n this.info.drawCalls++\n }\n\n /**\n * Fill a section plane's cut through its solids. Each pixel's faces behind the plane are counted\n * into the stencil - in through a front face, out through a back one - so where the count isn't\n * zero, the plane there is inside a solid. A square on the plane, lit like any surface, is then\n * drawn over just those pixels: at the plane's own depth, so faces lying in it can't fight it.\n * @param {FrameCap} cap @param {FrameDescription} frame @param {number} width @param {number} height\n */\n #cap(cap, frame, width, height) {\n const gl = this.gl\n const programs = this.#gpu.programs\n // the counting program, for plain and instanced solids\n const masks = [false, true].map((instanced) => programs.get('clip-mask', instanced ? ['INSTANCED', 'CLIP'] : ['CLIP'], CLIP_MASK))\n if (!masks.every((p) => programs.isReady(p))) {\n if (!this.#wait) {\n this.info.compiling++\n return\n }\n for (const instanced of [false, true]) programs.ready('clip-mask', instanced ? ['INSTANCED', 'CLIP'] : ['CLIP'], CLIP_MASK)\n }\n gl.enable(gl.STENCIL_TEST)\n gl.enable(gl.SCISSOR_TEST)\n gl.scissor(0, 0, width, height)\n gl.clearStencil(0)\n gl.clear(gl.STENCIL_BUFFER_BIT)\n gl.disable(gl.SCISSOR_TEST)\n // count every face, hidden or not, without drawing a thing\n gl.colorMask(false, false, false, false)\n gl.depthMask(false)\n gl.disable(gl.DEPTH_TEST)\n gl.disable(gl.CULL_FACE)\n gl.stencilFunc(gl.ALWAYS, 0, 0xff)\n gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.INCR_WRAP)\n gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.DECR_WRAP)\n for (const item of cap.items) {\n const program = masks[item.instances ? 1 : 0]\n gl.useProgram(program.program)\n program.set('uViewProjection', frame.camera.viewProjection)\n program.set('uModel', item.worldMatrix)\n program.set('uClipPlane', cap.plane)\n gl.frontFace(mat4.determinant(item.worldMatrix) < 0 ? gl.CW : gl.CCW)\n this.#gpu.resources.drawTriangles(item.geometry, item.instances)\n this.info.drawCalls++\n }\n gl.colorMask(true, true, true, true)\n // then the plane, just where the count says\n gl.stencilFunc(gl.NOTEQUAL, 0, 0xff)\n gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP)\n this.#draw(this.#capItem(cap), frame, false)\n gl.disable(gl.STENCIL_TEST)\n }\n\n /** A cap's square, laid on its plane over the cut and facing out of it. @param {FrameCap} cap @returns {DrawItem} */\n #capItem(cap) {\n const hex = cap.color.getHex()\n let material = this.#capMaterials.get(hex)\n if (!material) this.#capMaterials.set(hex, material = new Material({ color: cap.color.getStyle(), roughness: 0.6 }))\n // axes for the square: y along the plane's normal, x and z across it\n const [nx, ny, nz] = cap.plane\n const across = Math.abs(nx) < 0.9 ? [1, 0, 0] : [0, 1, 0]\n let ax = ny * across[2] - nz * across[1], ay = nz * across[0] - nx * across[2], az = nx * across[1] - ny * across[0]\n const l = Math.hypot(ax, ay, az)\n ax /= l\n ay /= l\n az /= l\n // x cross y gives z, so the square keeps facing +y - out of the cut\n const bx = ay * nz - az * ny, by = az * nx - ax * nz, bz = ax * ny - ay * nx\n const s = cap.radius * 1.05, c = cap.center\n const worldMatrix = /** @type {any} */ (new Float32Array([ax * s, ay * s, az * s, 0, nx, ny, nz, 0, bx * s, by * s, bz * s, 0, c[0], c[1], c[2], 1]))\n return { node: CAP_NODE, geometry: CAP_SQUARE, material, worldMatrix, instances: null, depth: 0, clip: null }\n }\n\n /**\n * @param {'mesh' | 'points' | 'lines'} kind @param {Material} material\n * @param {boolean} hasColors @param {boolean} instanced @param {boolean} hasUvs2\n * @returns {string[]}\n */\n #defines(kind, material, hasColors, instanced, hasUvs2) {\n const d = []\n if (material.vertexColors && hasColors) d.push('VERTEX_COLORS')\n if (kind === 'mesh') {\n if (!material.unlit) {\n d.push('LIT')\n for (const [slot, define] of Object.entries(MAP_DEFINES)) if (material[slot]) d.push(define)\n d.push(...this.#lightDefines)\n if (this.#environment) d.push('ENV_MAP')\n else if (this.#studio) d.push('STUDIO')\n if (material.transmission > 0) d.push('TRANSMISSION')\n if (material.clearcoat > 0) d.push('CLEARCOAT')\n if (material.sheen > 0) d.push('SHEEN')\n if (material.anisotropy > 0) d.push('ANISOTROPY')\n if (material.translucency > 0) d.push('TRANSLUCENCY')\n if (material.matcap) d.push('MATCAP')\n if (material.toon > 0) d.push('TOON')\n }\n if (material.map) d.push('MAP')\n if (material.emissiveMap) d.push('EMISSIVE_MAP')\n if (material.alphaTest > 0) d.push('ALPHA_TEST')\n if (material.flatShading) d.push('FLAT_SHADING')\n if (material.doubleSided) d.push('DOUBLE_SIDED')\n if (material.triplanar > 0 && MAP_SLOTS.some((slot) => material[slot])) d.push('TRIPLANAR')\n // maps on the second UV set read it - where the geometry has one\n const second = hasUvs2 ? material.textures.filter(([slot, t]) => t.uvSet === 1 && slot !== 'matcap') : []\n if (second.length) d.push('UV2', ...second.map(([slot]) => `${MAP_UNIFORMS[slot]}Set vUv2`))\n if (instanced) d.push('INSTANCED')\n } else if (kind === 'points') {\n if (material.map) d.push('MAP')\n if (material.sizeAttenuation) d.push('SIZE_ATTENUATION')\n } else if (material.dash > 0) d.push('DASHED')\n // (points drawn as squares add SPRITES - see #draw, which knows the node)\n return d\n }\n}\n\n","import { collect, toScreen } from './frame.js'\nimport { LabelLayer } from './labels.js'\nimport { DRAG_START, OrbitControl } from './OrbitControl.js'\nimport { cameraPreset, fitPoints, framingScale, presetDirection } from './presets.js'\nimport { EASES } from './ease.js'\nimport { Raycaster } from './Raycaster.js'\nimport { pickArea } from './area.js'\nimport { ChangeWatch } from './watch.js'\nimport { Box3 } from './value/Box3.js'\nimport { Color } from './value/Color.js'\nimport { Vec3 } from './value/Vec3.js'\nimport { Mat4 } from './value/Mat4.js'\nimport { Scene } from './scene/Scene.js'\nimport { Camera, PerspectiveCamera } from './scene/cameras.js'\nimport { DirectionalLight, HemisphereLight } from './scene/lights.js'\nimport { WebGLRenderer } from './webgl/WebGLRenderer.js'\nimport { checkOneOf, checkOptions, checkRange, describe, fail, warnOnce } from './validate.js'\n\n/** @import { OrbitOptions } from './OrbitControl.js' */\n/** @import { CameraPreset, FramingKeep } from './presets.js' */\n/** @import { Hit } from './Raycaster.js' */\n/** @import { FrameDescription, FrameHighlight } from './frame.js' */\n/** @import { Texture, TextureOptions } from './material/Texture.js' */\n/** @import { LabelStats } from './labels.js' */\n/** @import { ImageOptions } from './snapshot.js' */\n/** @import { Tooltip, TooltipContent } from './tooltip.js' */\n/** @import { ToneMapping, BloomOptions } from './webgl/WebGLRenderer.js' */\n/** @import { CameraOptions } from './scene/cameras.js' */\n/** @import { ColorInput, Vec3Input } from './types.js' */\n/** @import { Node } from './scene/Node.js' */\n/** @import { Keyboard, KeyboardOptions } from './keyboard.js' */\n/** @import { DebugDraw, DebugOptions } from './debug.js' */\n\n/**\n * @typedef {'auto' | 'always' | 'manual'} RenderMode\n * auto: draw when something visible changed (checked cheaply each frame); always: every frame;\n * manual: only when view.render() or view.invalidate() is called.\n */\n\n/**\n * @typedef {object} ViewOptions\n * @property {HTMLCanvasElement | string} [canvas] element or CSS selector; default: a new canvas filling the window\n * @property {Scene} [scene] default: a new Scene (from a description: create({ type: 'scene', ... }))\n * @property {Camera | CameraPreset | (CameraOptions & { fov?: number })} [camera] a camera, a preset\n * ('perspective', 'isometric', 'top', 'front', 'side' - fitted to the scene on the first frame), or\n * PerspectiveCamera options. Default: 'perspective' - a three-quarter view from the front right\n * and above, fitted to the scene\n * @property {boolean | OrbitOptions} [orbit] mouse/touch camera control (default false)\n * @property {ColorInput | Texture | TextureOptions | null} [background] shortcut for scene.background: a colour or a panorama\n * @property {RenderMode} [renderMode] when to draw (default 'auto': only when something changed)\n * @property {FramingKeep | { keep?: FramingKeep, aspect?: number }} [framing] what stays in view when the canvas\n * changes shape: 'height' (default - the width varies), 'width', or 'both' (nothing framed is ever cut off); or\n * { keep, aspect }, where aspect is the width / height the camera was set up for (default: the canvas's shape\n * when the camera was set or framed)\n * @property {ColorInput | null} [highlight] tint whatever is under the pointer with this colour (default none)\n * @property {(hit: Hit) => TooltipContent} [tooltip] what to show for the thing under the pointer - see tooltip()\n * @property {number} [pixelRatio] default min(devicePixelRatio, 2)\n * @property {boolean} [antialias] (default true)\n * @property {boolean} [outlineAntialias] soft-edged outlines with round corners (default: as antialias); change it\n * any time with view.renderer.outlineAntialias\n * @property {'auto' | 'own' | 'shared'} [context] which WebGL context draws it: 'own' gives the canvas one of\n * its own; 'shared' draws with the page's one shared context and copies the picture over, so a page can hold\n * any number of views (browsers allow about 16 live contexts). 'auto' (default): own for the first four\n * views on a page, shared after that\n * @property {ToneMapping} [toneMapping] 'neutral' keeps colours true (default), 'aces' is filmic, 'none' clips\n * @property {number} [exposure] (default 1)\n * @property {boolean | BloomOptions} [bloom] glow round the bright parts of the picture - emissive materials,\n * additive points and lines (default off). true for the defaults, or { strength, radius, threshold }\n * @property {boolean} [autoLight] light a scene that has no lights, with one console note (default true)\n * @property {number} [maxDelta] longest frame step in seconds, so a background tab doesn't jump (default 0.1)\n * @property {'auto' | boolean} [reducedMotion] cut motion short, for people it makes unwell: frame() jumps rather\n * than glides, auto-rotation holds, and charts change at once with their flows still. Default 'auto': as the\n * system's setting (prefers-reduced-motion), followed as it changes\n * @property {boolean | KeyboardOptions} [keyboard] use without a pointer: the canvas joins the page's tab order, and\n * the arrow keys step through what can be hovered or clicked - each with the hover tint, the tooltip and hover\n * handlers - with Enter or Space to click and Escape to leave. A screen reader hears each one. { label: (hit) =>\n * text } says what it hears (default: the tooltip's text, the data, or the name). Default false\n * @property {string | null} [description] what the view shows, for screen readers: the canvas's label. With keyboard\n * on and no description, one is made from the scene (charts describe themselves)\n * @property {boolean | DebugOptions} [debug] pictures for checking a scene: lights, shadow cameras, bounds,\n * normals, axes, the orbit target and a stats readout. true shows all but normals. Default false\n */\n\n/** @typedef {'click' | 'hover'} ViewEvent */\n/** @typedef {(hit: Hit | null, event: PointerEvent | MouseEvent | null) => void} ViewHandler */\n\nconst OPTIONS = ['canvas', 'scene', 'camera', 'orbit', 'background', 'renderMode', 'framing', 'highlight', 'tooltip', 'pixelRatio',\n 'antialias', 'outlineAntialias', 'context', 'toneMapping', 'exposure', 'bloom', 'autoLight', 'maxDelta', 'reducedMotion',\n 'keyboard', 'description', 'debug']\n// what debug: true shows - everything but normals, which bristle on a big model\n/** @type {Required<DebugOptions>} */\nconst DEBUG_ALL = { lights: true, shadows: true, bounds: true, normals: false, axes: true, camera: true, stats: 'top-left' }\nconst DEBUG_OPTIONS = Object.keys(DEBUG_ALL)\nconst CORNERS = ['top-left', 'top-right', 'bottom-left', 'bottom-right']\nconst FRAMING_OPTIONS = ['keep', 'aspect']\nconst HINTS = {\n renderer: 'the View makes its renderer - read it from view.renderer',\n controls: \"use orbit: true (or orbit options); the control is then view.controls\",\n container: \"use canvas: an element or selector (a full-window canvas is made when omitted)\",\n onClick: \"use view.on('click', (hit) => ...)\",\n onHover: \"use view.on('hover', (hit) => ...)\",\n frameloop: \"use renderMode: 'auto' | 'always' | 'manual'\",\n keep: \"use framing: { keep: 'width' | 'height' | 'both' }\",\n fit: \"use framing: { keep: 'both' } to keep everything framed in view as the canvas changes shape\",\n aspect: \"the canvas sets the aspect; framing: { aspect } says which shape the camera was set up for\",\n}\nconst EVENT_HINTS = {\n mouseover: 'hover', mouseenter: 'hover', mousemove: 'hover', pointermove: 'hover', pointerover: 'hover', pointerenter: 'hover',\n mouseleave: 'hover', pointerleave: 'hover', tap: 'click', pick: 'click', select: 'click', pointerdown: 'click', mousedown: 'click',\n}\n// how far the highlight colour is mixed in\nconst HIGHLIGHT_AMOUNT = 0.45\n// what the keyboard's focus is tinted with when nothing says otherwise - focus must always show\nconst FOCUS_COLOR = Color.fromInput('#ffcc00')\n// views that get a WebGL context of their own before 'auto' starts sharing one\nconst OWN_CONTEXTS = 4\n// above this many things to test (instances, triangles, points, segments), picking goes to the\n// GPU; below it, rays on the CPU are quicker than a GPU round trip\nconst GPU_PICKING = 5000\nlet ownContexts = 0\n\n/**\n * The one object most apps touch: it owns the canvas, renderer, camera, controls, loop and pointer\n * interaction. It draws only when something changed, so an idle view costs almost nothing.\n *\n * const view = new View({ canvas: '#c', orbit: true })\n * const cube = view.scene.add(new Mesh({ geometry: box(2), material: { color: 'orange' } }))\n * view.on('click', (hit) => console.log(hit?.node))\n * view.start((dt) => cube.rotateY(0.6 * dt))\n */\nexport class View {\n /** The options it takes, and hints for names people reach for instead. */\n static OPTIONS = OPTIONS\n static HINTS = HINTS\n /** What framing: { ... } takes. */\n static FRAMING_OPTIONS = FRAMING_OPTIONS\n /** @type {HTMLCanvasElement} */ canvas\n /** @type {Scene} */ scene\n /** @type {Camera} */ #camera\n /** @type {WebGLRenderer} */ renderer\n /** @type {OrbitControl | null} */ controls = null\n /** Seconds the loop has run. */\n time = 0\n /** Light the scene when it has none. */\n autoLight = true\n maxDelta = 0.1\n /** When to draw. @type {RenderMode} */\n renderMode = 'auto'\n /** @internal The last frame drawn. @type {FrameDescription | null} */\n lastFrame = null\n\n /** @type {((dt: number, t: number) => void) | null} */ #onFrame = null\n // time runs from the start, so update handlers (transitions, particles) work without start()\n #running = true\n #disposed = false\n #ownContext = false\n #ownCanvas = false\n #rafId = 0\n #lastTime = 0\n #dirty = true\n #onScreen = true\n #width = 0\n #height = 0\n #pixelRatio = 1\n #explicitPixelRatio = false\n #autoFrame = false\n // where a preset camera started, so fitting it on the first frame never undoes the app's own move\n /** @type {number[] | null} */ #autoFrameFrom = null\n // framing kept as the canvas changes shape: what to keep, the shape it was set for, and the\n // scale applied so far, so further changes stay relative (zooming by hand still works)\n /** @type {FramingKeep} */ #keep = 'height'\n #designed = 0\n #applied = 1\n #watch = new ChangeWatch()\n /** @type {(() => void)[]} */ #cleanup = []\n #labels\n /** @type {LabelStats | null} */ #labelStats = null\n // pointer interaction\n /** @type {{ click: Set<ViewHandler>, hover: Set<ViewHandler> }} */ #handlers = { click: new Set(), hover: new Set() }\n // the tooltip's code loads when first asked for, so apps without one don't carry it\n /** @type {Tooltip | null} */ #tooltip = null\n /** @type {((hit: Hit) => TooltipContent) | null} */ #tooltipContent = null\n #tooltipClass = ''\n #tooltipLoading = false\n /** @type {Color | null} */ #highlight = null\n /** @type {'auto' | boolean} */ #motion = 'auto'\n // keyboard use: its code loads when asked for; the thing it has stepped to shows as hovered\n /** @type {Keyboard | null} */ #keyboard = null\n /** @type {Hit | null} */ #keyFocus = null\n /** @type {string | null} */ #description = null\n // debug drawing: its code loads when turned on; the helpers are added to each frame, then taken out\n /** @type {Required<DebugOptions> | null} */ #debug = null\n /** @type {DebugDraw | null} */ #debugDraw = null\n #debugLoading = false\n #drawnAt = 0\n #frameMs = 0\n // the canvas had no role, so describing it gave it one - taken away again with the description\n #gaveRole = false\n // the system's prefers-reduced-motion, kept up to date\n #systemReduced = false\n /** @type {{ x: number, y: number, clientX: number, clientY: number, event: PointerEvent } | null} */ #pointer = null\n #pickPending = false\n // a hover pick is out on the GPU\n #hoverBusy = false\n #dragging = false\n /**\n * A node being dragged: from the press, until the pointer lets go.\n * @type {{ drag: import('./scene/Node.js').Drag, id: number, x: number, y: number, press: import('./value/Ray.js').Ray, started: boolean } | null}\n */\n #drag = null\n /** The orbit's pointer handlers, once it has handed the pointer to the view. @type {ReturnType<OrbitControl['handOverPointer']> | null} */\n #orbitPointer = null\n /** The press in progress, and whether it has moved far enough to be a drag rather than a click. @type {{ id: number, x: number, y: number, moved: boolean } | null} */\n #press = null\n /** @type {Hit | null} */ #hovered = null\n /** The camera on its way to where frame() put it: from and to, and how far along. @type {Flight | null} */\n #flight = null\n /** A label the pointer is on, as a hit on what it labels - the canvas can't see the pointer there. @type {Hit | null} */\n #labelHover = null\n // used for scenes without lights; never added to the scene itself\n #autoSky = new HemisphereLight({ sky: '#ffffff', ground: '#444444', intensity: 0.5 })\n #autoSun = new DirectionalLight({ direction: [-0.5, -1, -0.6], intensity: 1.5 })\n #noted = false\n\n /** @param {ViewOptions} [options] */\n constructor(options = {}) {\n checkOptions('View', options, OPTIONS, HINTS)\n this.canvas = resolveCanvas(options.canvas)\n // one it made itself goes with it\n this.#ownCanvas = options.canvas === undefined\n\n if (options.scene === undefined) this.scene = new Scene()\n else if (options.scene instanceof Scene) this.scene = options.scene\n else fail('View', `'scene' must be a Scene${options.scene && typeof options.scene === 'object' && 'type' in options.scene ? \" - build one from a description with create({ type: 'scene', ... })\" : `, got ${describe(options.scene)}`}`)\n if (options.background !== undefined) this.scene.background = options.background\n\n if (options.camera instanceof Camera) {\n this.#camera = options.camera\n } else if (typeof options.camera === 'string') {\n this.#camera = cameraPreset(options.camera)\n this.#autoFrame = true\n } else if (options.camera === undefined) {\n // a three-quarter view, fitted to whatever the scene holds on its first frame\n this.#camera = cameraPreset('perspective')\n this.#autoFrame = true\n } else {\n this.#camera = new PerspectiveCamera({ position: [0, 1.5, 6], target: [0, 0, 0], ...options.camera })\n }\n if (this.#autoFrame) this.#autoFrameFrom = cameraPlace(this.#camera)\n\n const context = options.context === undefined ? 'auto' : checkOneOf('View', 'context', options.context, ['auto', 'own', 'shared'])\n // the renderer checks these too; checked here, the error names the View\n if (options.exposure !== undefined) checkRange('View', 'exposure', options.exposure, 0)\n const shared = context === 'shared' || (context === 'auto' && ownContexts >= OWN_CONTEXTS)\n this.renderer = new WebGLRenderer({ canvas: this.canvas, shared, antialias: options.antialias, outlineAntialias: options.outlineAntialias, toneMapping: options.toneMapping, exposure: options.exposure, bloom: options.bloom })\n if (!shared) {\n this.#ownContext = true\n ownContexts++\n }\n // shadows and HDR environments load their code on first use, then want another frame\n this.renderer.onReady = () => {\n // picking may have just arrived, so look under the pointer again\n this.#pickPending = true\n this.invalidate()\n }\n if (options.autoLight !== undefined) this.autoLight = !!options.autoLight\n if (options.reducedMotion !== undefined) this.#setMotion(options.reducedMotion)\n if (options.maxDelta !== undefined) this.maxDelta = checkRange('View', 'maxDelta', options.maxDelta, 0, Infinity, { above: true })\n if (options.renderMode !== undefined) this.renderMode = checkOneOf('View', 'renderMode', options.renderMode, ['auto', 'always', 'manual'])\n if (options.pixelRatio !== undefined) {\n this.#pixelRatio = checkRange('View', 'pixelRatio', options.pixelRatio, 0, Infinity, { above: true })\n this.#explicitPixelRatio = true\n }\n if (options.orbit !== undefined && options.orbit !== false && options.orbit !== true &&\n (typeof options.orbit !== 'object' || Array.isArray(options.orbit) || options.orbit === null)) {\n fail('View', `'orbit' must be true, false or orbit options such as { autoRotate: true }, got ${describe(options.orbit)}`)\n }\n if (options.orbit) {\n const orbit = options.orbit === true ? {} : options.orbit\n // a plan view pans like a map unless told otherwise\n const mode = orbit.mode ?? (options.camera === 'top' ? 'map' : undefined)\n this.controls = new OrbitControl(this.camera, this.canvas, mode ? { ...orbit, mode } : orbit)\n // the view owns the pointer and gives the orbit the presses that aren't drags of a node\n this.#orbitPointer = this.controls.handOverPointer()\n }\n if (options.highlight !== undefined) this.#setHighlight(options.highlight)\n if (options.tooltip !== undefined) this.tooltip(options.tooltip)\n if (options.description !== undefined) this.description = options.description\n if (options.keyboard !== undefined && options.keyboard !== false) this.#loadKeyboard(options.keyboard)\n this.#labels = new LabelLayer(this.canvas, {\n interactive: (label) => labelHandlers(label, 'click').length > 0 || labelHandlers(label, 'hover').length > 0,\n on: (type, label, e) => this.#labelPointer(type, label, e),\n })\n if (options.debug !== undefined) this.debug = options.debug\n\n if (options.framing !== undefined) {\n // 'both' is short for { keep: 'both' }\n const f = typeof options.framing === 'string' ? { keep: options.framing } : options.framing\n checkOptions('View', f, FRAMING_OPTIONS, {}, 'framing')\n if (f.keep !== undefined) this.#keep = checkOneOf('View', 'framing.keep', f.keep, ['height', 'width', 'both'])\n if (f.aspect !== undefined) {\n if (!(f.aspect > 0)) fail('View', `framing.aspect is a width / height above 0, got ${describe(f.aspect)}`)\n this.#designed = f.aspect\n }\n }\n this.resize()\n this.#listen()\n this.#schedule()\n }\n\n /**\n * The camera drawn from. Set another camera, or a preset name to switch view - the orbit control\n * moves over, and a preset keeps looking at the same point, fitted to the scene.\n * @returns {Camera}\n */\n get camera() { return this.#camera }\n /** @param {Camera | CameraPreset} camera */\n set camera(camera) {\n if (typeof camera === 'string') {\n const old = /** @type {any} */ (this.#camera)\n const target = old.target ?? new Vec3()\n camera = cameraPreset(camera, { target, distance: Math.max(1e-3, old.position.distanceTo(target)) })\n this.#autoFrame = true\n } else {\n // a camera given explicitly stays where it was put, as one given to the constructor does\n this.#autoFrame = false\n }\n if (!(camera instanceof Camera)) fail('View', `'camera' must be a camera or a preset name, got ${describe(camera)}`)\n this.#flight = null\n this.#camera = camera\n if (this.#height) camera.aspect = this.#width / this.#height\n // a new camera is framed for the canvas as it is now\n this.#designed = camera.aspect\n this.#applied = 1\n if (this.controls) {\n // the control orbits the camera's target, so give it one where the old camera was looking\n camera.target ??= this.controls.target.clone()\n this.controls.camera = camera\n }\n if (this.#autoFrame) this.#autoFrameFrom = cameraPlace(camera)\n this.invalidate()\n }\n\n /**\n * Glow round the bright parts of the picture: null for none, or its settings. Set true, false or\n * { strength, radius, threshold }. (After changing its numbers in place, call invalidate().)\n * @returns {Required<BloomOptions> | null}\n */\n get bloom() { return this.renderer.bloom }\n /** @param {boolean | BloomOptions | null} v */\n set bloom(v) {\n this.renderer.bloom = v\n this.invalidate()\n }\n\n /** The colour mixed into whatever is under the pointer, or null for none. @returns {Color | null} */\n get highlight() { return this.#highlight }\n /** @param {ColorInput | null} v */\n set highlight(v) { this.#setHighlight(v) }\n\n /** @param {ColorInput | null} v */\n #setHighlight(v) {\n this.#highlight = v == null ? null : Color.fromInput(v, 'View')\n this.#pickPending = true\n this.invalidate()\n }\n\n /**\n * Is motion cut short - glides, auto-rotation, chart transitions? Set true or false, or 'auto' (the\n * default) to follow the system's setting. Read it for motion of your own, such as a timeline.\n * @returns {boolean}\n */\n get reducedMotion() { return this.#motion === 'auto' ? this.#systemReduced : this.#motion }\n /** @param {'auto' | boolean} v */\n set reducedMotion(v) { this.#setMotion(v) }\n\n /** @param {'auto' | boolean} v */\n #setMotion(v) {\n if (v !== 'auto' && typeof v !== 'boolean') fail('View', `'reducedMotion' is 'auto' (as the system's setting), true or false, got ${describe(v)}`)\n this.#motion = v\n this.invalidate()\n }\n\n /**\n * Debug drawing, or false: what it shows, as DebugOptions. Assign true for everything but normals,\n * options for some, or false. Its code loads the first time it's turned on.\n *\n * view.debug = { lights: true, shadows: true, bounds: 'hovered', stats: 'bottom-right' }\n * @returns {boolean | DebugOptions} the options in force, every one given, or false\n */\n get debug() { return this.#debug ?? false }\n /** @param {boolean | DebugOptions} v */\n set debug(v) {\n this.#debug = debugOptions(v)\n if (this.#debug && !this.#debugDraw && !this.#debugLoading) {\n this.#debugLoading = true\n import('./debug.js').then(({ DebugDraw }) => {\n this.#debugLoading = false\n if (this.#disposed) return\n this.#debugDraw = new DebugDraw(this.#labels.root)\n this.invalidate()\n })\n }\n // hovered helpers need the pointer followed\n if (this.#debug && (this.#debug.bounds === 'hovered' || this.#debug.normals === 'hovered')) this.#pickPending = true\n if (!this.#debug) this.#debugDraw?.stats(false, /** @type {any} */ ({}), 0, 0)\n this.invalidate()\n }\n\n /**\n * What the view shows, for screen readers - the canvas's label - or null. With keyboard on and no\n * description, one is made from the scene.\n * @returns {string | null}\n */\n get description() { return this.#description }\n /** @param {string | null} v */\n set description(v) {\n if (v !== null && typeof v !== 'string') fail('View', `'description' is text for screen readers, or null, got ${describe(v)}`)\n this.#description = v\n if (this.#keyboard) {\n this.#keyboard.setDescription(v)\n return\n }\n const canvas = this.canvas\n if (v === null) {\n canvas.removeAttribute('aria-label')\n if (this.#gaveRole) canvas.removeAttribute('role')\n this.#gaveRole = false\n return\n }\n canvas.setAttribute('aria-label', v)\n // a picture, to a screen reader, unless the page has said otherwise\n if (!canvas.hasAttribute('role')) {\n canvas.setAttribute('role', 'img')\n this.#gaveRole = true\n }\n }\n\n /** Canvas width in CSS pixels. */\n get width() { return this.#width }\n /** Canvas height in CSS pixels. */\n get height() { return this.#height }\n\n /** Resolves when every texture in the scene has loaded. @returns {Promise<void>} */\n get ready() {\n return this.scene.ready\n }\n\n /** The thing under the pointer, as of the last pointer move or redraw. @returns {Hit | null} */\n get hovered() {\n return this.#hovered\n }\n\n /** @internal\n * A layer over the canvas for HTML of your own - a title, a key, buttons. It tracks the canvas and\n * doesn't take pointer events itself; give children `pointer-events: auto` to make them clickable.\n * @returns {HTMLDivElement}\n */\n get overlay() {\n return this.#labels.root\n }\n\n /**\n * Call fn(dt, t) every frame (seconds), for app-level animation, and resume time if it was\n * stopped. Time - and the scene's update handlers - run from the start anyway; in 'auto' mode a\n * frame is still only drawn when something changed.\n * @param {(dt: number, t: number) => void} [fn]\n * @returns {this}\n */\n start(fn) {\n if (fn) this.#onFrame = fn\n if (!this.#running) {\n this.#running = true\n this.#lastTime = 0\n }\n this.#schedule()\n return this\n }\n\n /** Freeze time: the frame function and update handlers stop until start(). The view still redraws on changes. @returns {this} */\n stop() {\n this.#running = false\n return this\n }\n\n /** Is time running (not stopped)? */\n get running() {\n return this.#running\n }\n\n /**\n * Draw on the next frame even if nothing seems to have changed - after editing data the View\n * can't see, such as geometry arrays without needsUpdate(). Needed in 'manual' mode.\n * @returns {this}\n */\n invalidate() {\n this.#dirty = true\n this.#schedule()\n return this\n }\n\n /**\n * Advance exactly one frame by dt seconds and draw it. Deterministic - for tests, screenshots\n * and stepping a paused scene.\n * @param {number} dt\n * @returns {FrameDescription}\n */\n step(dt) {\n this.time += dt\n this.#onFrame?.(dt, this.time)\n // the same order as the live loop, so a stepped frame is the frame a user sees\n this.scene.motionReduced = this.reducedMotion\n this.scene.update(dt, this.time)\n this.#updateControls(dt)\n return this.#render(true)\n }\n\n /**\n * Move the camera by its control: auto-rotation and the glide after a drag. That isn't the app\n * moving the camera, so a camera still waiting to be fitted to the scene stays waiting.\n * @param {number} dt\n */\n #updateControls(dt) {\n if (this.#flight) return this.#fly(dt)\n if (!this.controls) return\n const waiting = this.#autoFrame && samePlace(cameraPlace(this.camera), this.#autoFrameFrom)\n this.controls.update(dt, this.reducedMotion)\n if (waiting) this.#autoFrameFrom = cameraPlace(this.camera)\n }\n\n /**\n * Draw the current state now, without advancing time. Shaders compile in the background on the\n * first frames, and what is still compiling appears a frame or two later.\n * @returns {FrameDescription}\n */\n render() {\n return this.#render(false)\n }\n\n /** @param {boolean} wait wait for shaders, for a complete frame (step, toImage) */\n #render(wait) {\n if (this.#autoFrame) {\n // fitted to the canvas as laid out now: a page still being built (a grid of tiles filling up)\n // can change its shape before the browser reports the resize, which comes after this frame\n this.resize()\n const bounds = this.scene.bounds\n // the app moved the camera itself: leave it where it put it\n if (!samePlace(cameraPlace(this.camera), this.#autoFrameFrom)) this.#autoFrame = false\n // what is drawn from the preset's direction, not every candidate label set\n else if (!bounds.isEmpty()) this.frame(this.scene)\n }\n this.scene.updateWorldTree()\n const frame = collect(this.scene, this.camera)\n if (this.autoLight && frame.lights.length === 0) this.#addAutoLights(frame)\n frame.time = this.time\n frame.highlight = this.#highlightFor(this.#hovered)\n this.#occlude(frame)\n // debug helpers go on the end of the frame for drawing, and come off again after: never picked,\n // explained or kept in lastFrame\n const debug = this.#debug && this.#debugDraw\n ? this.#debugDraw.add(frame, this.#debug, { camera: this.camera, hovered: this.#hovered, bounds: this.scene.boundsFrom(this.camera) })\n : null\n const started = performance.now()\n this.renderer.renderFrame(frame, { wait })\n if (debug) {\n frame.opaque.length -= debug.opaque\n frame.transparent.length -= debug.transparent\n }\n if (this.#debugDraw) {\n const now = performance.now()\n // time between frames drawn one after another, smoothed; after a pause, none\n const gap = this.#drawnAt ? now - this.#drawnAt : 0\n this.#frameMs = gap > 0 && gap < 250 ? this.#frameMs * 0.9 + gap * 0.1 : 0\n this.#drawnAt = now\n this.#debugDraw.stats(this.#debug?.stats ?? false, this.renderer.info, this.#frameMs, now - started)\n }\n this.#labelStats = this.#labels.update(frame.labels, frame.overlays)\n // a node with its own tooltip needs the tooltip's code\n if (frame.tooltips && !this.#tooltip) this.#loadTooltip()\n this.lastFrame = frame\n this.#dirty = false\n // remember what was drawn - including what drawing changed, such as fitting the camera - so\n // the next frame compares against it and doesn't draw the same picture again\n if (this.renderMode === 'auto') this.#watch.changed(this.scene, this.camera, this.time)\n // things may have moved under a still pointer - or the keyboard's focus moved on screen\n if ((this.#pointer || this.#keyFocus) && this.#needsHover()) this.#pickPending = true\n return frame\n }\n\n /** Match the drawing buffer and camera to the canvas's displayed size. Automatic; call after manual changes. */\n resize() {\n const cw = this.canvas.clientWidth, ch = this.canvas.clientHeight\n // hidden (display: none, a closed tab): keep the size it had, and pick up where it was when shown\n if ((!cw || !ch) && this.#width) return\n // a canvas sized only by its width and height attributes grows with every buffer it is given - at a\n // pixel ratio of 2, without end. Seen growing to exactly the buffer just set, it is held at its size\n if (this.#width && this.#pixelRatio !== 1 && cw === Math.round(this.#width * this.#pixelRatio) && ch === Math.round(this.#height * this.#pixelRatio)) {\n this.canvas.style.width = `${this.#width}px`\n this.canvas.style.height = `${this.#height}px`\n return\n }\n const w = cw || this.canvas.width || 1\n const h = ch || this.canvas.height || 1\n if (!this.#explicitPixelRatio) this.#pixelRatio = Math.min(globalThis.devicePixelRatio || 1, 2)\n this.#width = w\n this.#height = h\n this.renderer.setSize(w, h, this.#pixelRatio)\n this.camera.aspect = w / h\n // keeping the framing can move the camera; that isn't the app placing it, so a camera still\n // waiting to be fitted to the scene stays waiting\n const waiting = this.#autoFrame && samePlace(cameraPlace(this.camera), this.#autoFrameFrom)\n this.#keepFraming()\n if (waiting) this.#autoFrameFrom = cameraPlace(this.camera)\n this.#dirty = true\n }\n\n /**\n * Move the camera so a node, a box or (with no argument) the whole scene fills the view. The orbit\n * target moves to its centre. It keeps the viewing direction unless given one - a preset's name\n * ('perspective', 'top', 'front'...) or a vector from the target towards the camera - and with a\n * duration it glides there, as a tour or a Reset button wants.\n *\n * view.frame(rack, { duration: 0.8 }) // fly to the rack\n * view.frame(undefined, { direction: 'perspective', duration: 0.6 }) // back to the start\n * @param {Node | Box3} [target] (default the scene)\n * @param {{ padding?: number, direction?: CameraPreset | Vec3Input, duration?: number }} [options] padding is\n * the margin around it, as a fraction of its size: 0 is a tight fit, 0.2 (the default) leaves a fifth.\n * duration is in seconds (default 0: straight there); a press or the wheel stops the glide, and with\n * reducedMotion it goes straight there\n * @returns {this}\n */\n frame(target = this.scene, { padding = 0.2, direction: towards, duration = 0 } = {}) {\n checkRange('View', 'frame() duration', duration, 0)\n const cam = /** @type {any} */ (this.camera)\n const from = placeOf(cam)\n this.#flight = null\n const fit = this.#fit('frame', target, padding, towards)\n // an explicit frame replaces the preset camera's fit on the first frame\n this.#autoFrame = false\n if (!fit) return this\n setPlace(cam, fit.place)\n cam.near = fit.near ?? cam.near\n cam.far = Math.max(cam.far, fit.far)\n // framed for the canvas as it is now\n this.#designed = cam.aspect\n this.#applied = 1\n if (duration > 0 && !this.reducedMotion) {\n // the camera starts where it was and glides there, frame by frame\n this.#flight = { from, to: placeOf(cam), time: 0, duration }\n setPlace(cam, from)\n }\n this.invalidate()\n return this\n }\n\n /**\n * Where frame() would put the camera, without moving it: its position, target and - for an\n * orthographic camera - height, or null when there is nothing to frame. For a camera of your own\n * that eases after something moving rather than jumping each frame:\n *\n * const aim = view.framing(debris)\n * if (aim) {\n * view.camera.position.lerp(aim.position, 0.1)\n * view.camera.target.lerp(aim.target, 0.1)\n * }\n * @param {Node | Box3} [target] (default the scene)\n * @param {{ padding?: number, direction?: CameraPreset | Vec3Input }} [options] as frame()\n * @returns {{ position: Vec3, target: Vec3, height?: number } | null}\n */\n framing(target = this.scene, { padding = 0.2, direction } = {}) {\n const fit = this.#fit('framing', target, padding, direction)\n if (!fit) return null\n const { position, target: at, height } = fit.place\n return height === undefined ? { position, target: at } : { position, target: at, height }\n }\n\n /**\n * The camera's place to frame something, worked out without moving it - for frame() and framing().\n * @param {string} method its caller, for errors @param {Node | Box3} target @param {number} padding\n * @param {CameraPreset | Vec3Input | undefined} towards\n * @returns {{ place: Place, near: number | undefined, far: number } | null}\n */\n #fit(method, target, padding, towards) {\n if (!(padding >= 0)) fail('View', `${method}() padding is the margin around, as a fraction of the size (0.2 = 20%), got ${describe(padding)}`)\n if (padding >= 1) warnOnce(this, `${method}() padding ${padding} leaves a margin of ${Math.round(padding * 100)}% - it is a fraction of the size (0.2 = 20%)`)\n const cam = /** @type {any} */ (this.camera)\n const direction = towards === undefined ? cam.position.clone().sub(cam.target ?? new Vec3()).normalize()\n : typeof towards === 'string' ? presetDirection(/** @type {CameraPreset} */ (towards)) : Vec3.fromInput(towards, 'View').normalize()\n if (towards !== undefined && !(direction.len() > 0)) fail('View', `${method}() direction is a preset name or a vector from the target towards the camera, got ${describe(towards)}`)\n if (direction.len() === 0) direction.set(0, 0.3, 1).normalize()\n const points = target instanceof Box3 ? corners(target) : this.#drawnPoints(target, direction)\n if (!points.length) return null\n const ortho = cam.constructor.type === 'orthographic-camera'\n const { center, size } = fitPoints(points, direction, { aspect: cam.aspect, fov: ortho ? undefined : cam.fov, padding })\n const radius = Math.max(1e-3, ...points.map((p) => Math.hypot(p[0] - center[0], p[1] - center[1], p[2] - center[2])))\n if (ortho) {\n return { place: { position: center.clone().add(direction.clone().multiplyScalar(radius * 4)), target: center, height: size },\n near: undefined, far: radius * 10 }\n }\n // keep the near/far range sensible for the model's size\n const distance = size\n return { place: { position: center.clone().add(direction.clone().multiplyScalar(distance)), target: center },\n near: Math.max(1e-3, distance / 1000), far: distance * 10 }\n }\n\n /**\n * One frame of a glide: round the target as it moves, closing the distance evenly, so the picture\n * turns and zooms rather than cutting through what is in view.\n * @param {number} dt\n */\n #fly(dt) {\n const f = /** @type {Flight} */ (this.#flight)\n f.time = Math.min(f.duration, f.time + dt)\n const e = EASES.inOut(f.time / f.duration)\n const cam = /** @type {any} */ (this.camera)\n const target = f.from.target.clone().lerp(f.to.target, e)\n const d0 = f.from.position.clone().sub(f.from.target), d1 = f.to.position.clone().sub(f.to.target)\n const r0 = d0.len() || 1e-6, r1 = d1.len() || 1e-6\n const way = turnBetween(d0.multiplyScalar(1 / r0), d1.multiplyScalar(1 / r1), e)\n setTarget(cam, target)\n cam.position.copy(target).add(way.multiplyScalar(r0 * (r1 / r0) ** e))\n if (f.to.height !== undefined) cam.height = f.from.height * (f.to.height / f.from.height) ** e\n if (f.time >= f.duration) {\n setPlace(cam, f.to)\n this.#flight = null\n }\n this.invalidate()\n }\n\n /**\n * The corners of each thing a node draws seen from along a direction - leaving out what a camera\n * there wouldn't show (hidden nodes, showFrom sets turned away), measured from where framing will\n * put the camera. All its bounds' corners when that leaves nothing.\n * @param {Node} node @param {Vec3} direction from the node towards the camera\n * @returns {number[][]}\n */\n #drawnPoints(node, direction) {\n const all = node.bounds\n if (all.isEmpty()) return []\n const cam = this.camera, at = cam.position.clone()\n cam.position.copy(all.getCenter()).add(direction.clone().multiplyScalar(Math.max(all.getRadius(), 1e-3) * 3))\n cam.updateWorld()\n const points = drawnPoints(node, cam)\n cam.position.copy(at)\n cam.updateWorld()\n return points.length ? points : corners(all)\n }\n\n /**\n * The nearest hit under a canvas position - CSS pixels from the canvas's top left, or a pointer\n * event. Found on the GPU from the last frame drawn (one pass, however many instances), then made\n * exact on the CPU; on the CPU alone until the picking code has loaded.\n * @param {number | MouseEvent} x\n * @param {number} [y]\n * @returns {Hit | null}\n */\n pick(x, y) {\n if (typeof x === 'object') {\n const rect = this.canvas.getBoundingClientRect()\n y = x.clientY - rect.top\n x = x.clientX - rect.left\n }\n const frame = this.#gpuFrame()\n const found = frame ? this.renderer.pick(frame, x, /** @type {number} */ (y)) : undefined\n if (found === undefined) return this.pickAll(x, y)[0] ?? null\n return found && this.#exact(found, frame)\n }\n\n /**\n * The ray from the camera through a canvas position - CSS pixels from its top left, or a pointer\n * event - in world space: for finding where the pointer is on a floor or any plane.\n *\n * const ray = view.rayAt(event)\n * const t = ray.intersectPlane([0, 1, 0], [0, 0, 0])\n * if (t !== null) chair.position.copy(ray.at(t))\n * @param {number | MouseEvent} x\n * @param {number} [y]\n * @returns {import('./value/Ray.js').Ray}\n */\n rayAt(x, y) {\n if (typeof x === 'object') {\n const rect = this.canvas.getBoundingClientRect()\n y = x.clientY - rect.top\n x = x.clientX - rect.left\n }\n const ndc = [(x / (this.#width || 1)) * 2 - 1, 1 - (/** @type {number} */ (y) / (this.#height || 1)) * 2]\n return new Raycaster().setFromCamera(ndc, this.camera).ray\n }\n\n /** The last frame, when it is big enough that picking on the GPU pays. */\n #gpuFrame() {\n const frame = this.lastFrame\n if (!frame) return null\n let work = 0\n for (const { node, geometry, instances, material } of [...frame.opaque, ...frame.transparent]) {\n // a shader hook moves vertices where only the GPU knows: picked there, however small the scene\n if (material.shader?.vertex) return frame\n const mode = /** @type {any} */ (node).drawMode\n work += instances ? instances.count : mode === 'points' ? geometry.drawnVertices : mode === 'lines' ? geometry.drawnCount / 2 : geometry.drawnCount / 3\n }\n return work > GPU_PICKING ? frame : null\n }\n\n /**\n * A GPU hit made exact: the ray against just that instance, point or segment, for the point,\n * face, normal and uv.\n * @param {import('./webgl/picking.js').GPUHit} found @param {FrameDescription} frame\n * @returns {Hit}\n */\n #exact(found, frame) {\n const node = /** @type {any} */ (found.item.node)\n const raycaster = new Raycaster().setFromCamera(found.ndc, this.camera)\n // moved by a shader hook, the CPU's copy isn't where it was drawn: the GPU's depth is the hit\n const hit = node.material.shader?.vertex ? null : raycaster.intersectElement(node, found.element)\n if (hit) return hit\n // the ray grazed an edge the GPU drew: place the hit at the depth the GPU found\n const inverse = new Mat4().copy(frame.camera.viewProjection).invert()\n const point = new Vec3(found.ndc[0], found.ndc[1], found.ndc[2]).applyMatrix4(inverse)\n const instanced = 'instanceMatrices' in node, element = found.element\n const indexed = instanced || node.drawMode !== 'triangles'\n return { node, point, distance: point.distanceTo(raycaster.ray.origin), normal: null, face: indexed && !instanced ? element : null,\n instance: instanced ? element : null, uv: null, datum: node.datumAt(indexed ? element : null) }\n }\n\n /**\n * Where a world position is on the canvas - CSS pixels from its top left - with its depth (0 at\n * the near plane, 1 at the far) and whether it's in view: for placing HTML of your own over the\n * scene, beside what it's about.\n *\n * const { x, y } = view.project(cube.worldPosition)\n * @param {Vec3Input} point\n * @returns {{ x: number, y: number, depth: number, visible: boolean }}\n */\n project(point) {\n const { ndc: [x, y, z], visible } = toScreen(Vec3.fromInput(point, 'View'), this.#viewProjection())\n return { x: (x * 0.5 + 0.5) * this.#width, y: (0.5 - y * 0.5) * this.#height, depth: z * 0.5 + 0.5, visible }\n }\n\n /**\n * The rectangle on the canvas that a node, a box or (with no argument) the whole scene covers - CSS\n * pixels, from the corners of each thing the camera draws of it (as node.boundsFrom counts them).\n * Null when there's nothing there, or part of it is behind the camera.\n *\n * const { left, top, width } = view.screenBounds(model) // put a title above it\n * @param {Node | Box3} [target]\n * @returns {{ left: number, top: number, right: number, bottom: number, width: number, height: number } | null}\n */\n screenBounds(target = this.scene) {\n const points = target instanceof Box3 ? corners(target) : drawnPoints(target, this.camera)\n if (!points.length) return null\n let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity\n for (const point of points) {\n const { x, y, depth } = this.project(point)\n if (!(depth >= 0 && depth <= 1)) return null\n left = Math.min(left, x)\n right = Math.max(right, x)\n top = Math.min(top, y)\n bottom = Math.max(bottom, y)\n }\n return { left, top, right, bottom, width: right - left, height: bottom - top }\n }\n\n /** The camera's world to clip space matrix, up to date. @returns {Mat4} */\n #viewProjection() {\n const camera = this.camera\n camera.updateWorld()\n return new Mat4().multiplyMatrices(camera.projectionMatrix, camera.viewMatrix)\n }\n\n /**\n * Everything inside an area of the canvas, nearest first: a box `{ x, y, width, height }` or a\n * lasso of `[x, y]` points, CSS pixels from the canvas's top left. Each point, instance and line\n * segment is its own hit, found by where it is (a mesh by its middle) - hidden behind others or\n * not - so a box dragged over a scatter selects that region of it.\n *\n * const picked = view.pickArea({ x: 40, y: 30, width: 200, height: 120 }).map((h) => h.datum)\n * @param {import('./area.js').PickArea} area\n * @returns {Hit[]}\n */\n pickArea(area) {\n this.scene.updateWorldTree()\n return pickArea(this.scene, this.camera, this.#viewProjection(), this.#width, this.#height, area)\n }\n\n /** Every hit under a canvas position, nearest first. @param {number | MouseEvent} x @param {number} [y] @returns {Hit[]} */\n pickAll(x, y) {\n if (typeof x === 'object') {\n const rect = this.canvas.getBoundingClientRect()\n y = x.clientY - rect.top\n x = x.clientX - rect.left\n }\n const ndc = [(x / this.#width) * 2 - 1, 1 - (/** @type {number} */ (y) / this.#height) * 2]\n const raycaster = new Raycaster().setFromCamera(ndc, this.camera)\n // a few pixels' tolerance for points and lines, as world units at the target's distance\n const cam = /** @type {any} */ (this.camera)\n const distance = cam.position.distanceTo(cam.target ?? [0, 0, 0])\n const worldPerPixel = cam.constructor.type === 'orthographic-camera'\n ? cam.height / this.#height\n : 2 * distance * Math.tan(cam.fov * Math.PI / 360) / this.#height\n raycaster.threshold = 4 * worldPerPixel\n this.scene.updateWorldTree()\n return raycaster.intersect(this.scene)\n }\n\n /**\n * Listen for clicks on, or hovering over, the scene. Handlers get the hit (with .node, .instance\n * and .datum) or null for empty space. 'hover' fires when the thing under the pointer changes,\n * including to null when it leaves. Returns a function that removes the handler.\n *\n * view.on('click', (hit) => hit && select(hit.datum))\n * @param {ViewEvent} type\n * @param {ViewHandler} fn\n * @returns {() => void}\n */\n on(type, fn) {\n if (!(type in this.#handlers)) {\n const hint = EVENT_HINTS[type]\n if (hint) fail('View', `on('${type}') - use '${hint}'${hint === 'hover' ? ', which fires as the thing under the pointer changes (null when it leaves)' : ''}`)\n checkOneOf('View', 'event', type, ['click', 'hover'])\n }\n if (typeof fn !== 'function') fail('View', `on('${type}', fn) needs a function, got ${describe(fn)}`)\n const set = this.#handlers[type]\n set.add(fn)\n this.#pickPending = true\n return () => set.delete(fn)\n }\n\n /**\n * Show a tooltip by the pointer for whatever it is over. The function gets the hit and returns\n * text (new lines kept), an element, or { title, rows } - rows as { name: value } - or null for\n * none. Style it with the .phoria-tooltip class. Pass null to remove it.\n *\n * view.tooltip((hit) => ({ title: hit.datum.name, rows: { Sales: hit.datum.sales } }))\n * @param {((hit: Hit) => TooltipContent) | null} content\n * @param {{ className?: string }} [options]\n * @returns {this}\n */\n tooltip(content, { className } = {}) {\n if (content !== null && typeof content !== 'function') fail('View', `tooltip() takes a function (hit) => text, or null, got ${describe(content)}`)\n this.#tooltipContent = content\n if (className !== undefined) this.#tooltipClass = className\n if (this.#tooltip) this.#tooltip.el.className = `phoria-tooltip${this.#tooltipClass ? ` ${this.#tooltipClass}` : ''}`\n if (content) this.#loadTooltip()\n this.#pickPending = true\n return this\n }\n\n // the tooltip's code loads when first needed, so apps without one don't carry it\n #loadTooltip() {\n if (this.#tooltipLoading) return\n this.#tooltipLoading = true\n import('./tooltip.js').then(({ Tooltip }) => {\n if (this.#disposed) return\n this.#tooltip = new Tooltip((hit) => this.#tooltipFor(hit)?.(hit), this.#tooltipClass)\n this.#pickPending = true\n this.#schedule()\n })\n }\n\n /** @param {true | KeyboardOptions} options */\n #loadKeyboard(options) {\n if (options !== true && (typeof options !== 'object' || options === null || Array.isArray(options))) {\n fail('View', `'keyboard' is true, false or { label: (hit) => text }, got ${describe(options)}`)\n }\n const o = options === true ? {} : options\n checkOptions('View', o, ['label'], { describe: \"use 'label: (hit) => text'\", text: \"use 'label: (hit) => text'\" }, 'keyboard')\n if (o.label !== undefined && typeof o.label !== 'function') fail('View', `keyboard.label is a function (hit) => text, got ${describe(o.label)}`)\n import('./keyboard.js').then(({ Keyboard }) => {\n if (this.#disposed) return\n this.#keyboard = new Keyboard(this, {\n focus: (hit) => {\n this.#keyFocus = hit\n this.#pickPending = true\n this.invalidate()\n },\n press: (hit) => {\n for (const fn of handlersAbove(hit.node, 'click')) fn(hit)\n for (const fn of this.#handlers.click) fn(hit, null)\n },\n tooltip: (hit) => this.#tooltipFor(hit)?.(hit),\n viewWide: () => this.#handlers.hover.size > 0 || this.#handlers.click.size > 0 || !!this.#tooltipContent,\n }, o)\n this.#keyboard.setDescription(this.#description)\n })\n }\n\n /** Where the keyboard's focus shows - its middle, on screen - in place of the pointer. @param {Hit} hit */\n #keyAt(hit) {\n const { x, y } = this.project(hit.point), rect = this.canvas.getBoundingClientRect()\n return { x, y, clientX: rect.left + x, clientY: rect.top + y, event: null }\n }\n\n /** The nearest node tooltip above the hit, or the View's. @param {Hit} hit */\n #tooltipFor(hit) {\n for (let n = /** @type {any} */ (hit.node); n; n = n.parent) if (n.tooltip) return n.tooltip\n return this.#tooltipContent\n }\n\n /**\n * The current picture as an image file (PNG by default), with the visible labels painted in.\n *\n * const png = await view.toImage()\n * @param {ImageOptions} [options]\n * @returns {Promise<Blob>}\n */\n async toImage(options) {\n const { snapshot } = await import('./snapshot.js')\n // draw - complete, shaders and all - and read back in the same task, while the drawing\n // buffer is still there\n this.#render(true)\n return snapshot(this.canvas, this.#labels.shown, options ?? {}, this.#labels.leaders)\n }\n\n /**\n * A plain-text report of what the view is drawing - camera, what is drawn and culled, bounds,\n * lights, labels - with warnings for the usual reasons a picture is wrong (\"nothing in view\").\n * Draws a fresh frame first.\n *\n * console.log(await view.explain())\n * @returns {Promise<string>}\n */\n async explain() {\n const { explain } = await import('./explain.js')\n const frame = this.render()\n let nodes = 0\n const notes = []\n this.scene.traverse((n) => {\n nodes++\n // nodes that can describe themselves (charts) add a line each\n if (n !== this.scene && typeof (/** @type {any} */ (n)).explain === 'function') notes.push(/** @type {any} */ (n).explain())\n })\n // how much of the view the scene covers: what is drawn, projected - a share of each side\n const drawn = this.scene.boundsFrom(this.camera), onScreen = this.screenBounds(this.scene)\n const fills = onScreen ? { height: onScreen.height / this.#height, width: onScreen.width / this.#width } : null\n return explain({\n notes, fills,\n width: this.#width, height: this.#height, pixelRatio: this.#pixelRatio, renderMode: this.renderMode, running: this.#running,\n sharedContext: this.renderer.shared,\n frame, labels: this.#labelStats, bounds: drawn, nodes, autoLight: this.autoLight,\n contextLost: !!this.renderer.gl?.isContextLost?.(),\n interaction: { hover: this.#handlers.hover.size, click: this.#handlers.click.size, tooltip: !!this.#tooltipContent, highlight: !!this.#highlight,\n keyboard: !!this.#keyboard, reducedMotion: this.reducedMotion, description: this.canvas.getAttribute?.('aria-label') ?? this.#description },\n debug: this.#debug,\n })\n }\n\n /**\n * Stop the loop, remove listeners, labels and the tooltip, and free GPU resources - the context\n * itself when the view has its own, or what only this view drew when it shares one.\n */\n dispose() {\n if (this.#disposed) return\n this.#disposed = true\n this.#running = false\n cancelAnimationFrame(this.#rafId)\n for (const fn of this.#cleanup) fn()\n this.controls?.dispose()\n this.#labels.dispose()\n this.#tooltip?.dispose()\n this.#keyboard?.dispose()\n this.#debugDraw?.dispose()\n if (this.#description !== null && !this.#keyboard) this.description = null\n this.renderer.dispose(this.scene)\n if (this.#ownContext) ownContexts--\n if (this.#ownCanvas) this.canvas.remove()\n }\n\n // widen or narrow the view so the framing chosen with `framing.keep` survives a change of shape\n #keepFraming() {\n const cam = /** @type {any} */ (this.#camera)\n if (!this.#designed) this.#designed = cam.aspect\n const scale = framingScale(this.#keep, this.#designed, cam.aspect)\n const k = scale / this.#applied\n this.#applied = scale\n if (Math.abs(k - 1) < 1e-9) return\n if (cam.constructor.type === 'orthographic-camera') cam.height *= k\n else if (cam.target) {\n const offset = cam.position.clone().sub(cam.target).multiplyScalar(k)\n cam.position.copy(cam.target).add(offset)\n } else {\n // no target to move away from: widen the field of view instead\n cam.fov = Math.min(170, 2 * Math.atan(Math.tan(cam.fov * Math.PI / 360) * k) * 360 / Math.PI)\n }\n }\n\n // One requestAnimationFrame per frame at most, and none while the canvas is off screen or (in\n // manual mode) while there is nothing to do.\n #schedule() {\n if (this.#rafId || this.#disposed || !this.#onScreen) return\n if (this.renderMode === 'manual' && !(this.#running && this.#onFrame) && !this.#dirty && !this.#pickPending) return\n this.#rafId = requestAnimationFrame(this.#tick)\n }\n\n /** @param {number} now */\n #tick = (now) => {\n this.#rafId = 0\n const dt = this.#lastTime ? Math.min(this.maxDelta, (now - this.#lastTime) / 1000) : 0\n this.#lastTime = now\n try {\n if (this.#running) {\n this.time += dt\n this.#onFrame?.(dt, this.time)\n this.scene.motionReduced = this.reducedMotion\n this.scene.update(dt, this.time)\n }\n this.#updateControls(dt)\n if (this.#pickPending) this.#updateHover()\n const draw = this.#dirty || this.renderMode === 'always' ||\n (this.renderMode === 'auto' && this.#watch.changed(this.scene, this.camera, this.time))\n if (draw) this.render()\n } finally {\n // the next frame comes even if this one threw - the error still reaches the console, but one\n // bad handler doesn't freeze the view. In manual mode, sleep until something asks for a frame\n if (this.renderMode !== 'manual' || (this.#running && this.#onFrame) || this.#dirty || this.#pickPending) this.#schedule()\n }\n }\n\n #needsHover() {\n return this.#handlers.hover.size > 0 || !!this.#tooltipContent || !!this.#highlight || this.#handlers.click.size > 0 ||\n !!this.lastFrame?.interactive || this.#debugHovers()\n }\n\n /** Does debug draw something for what is under the pointer? */\n #debugHovers() {\n return !!this.#debug && (this.#debug.bounds === 'hovered' || this.#debug.normals === 'hovered')\n }\n\n // pick under the pointer and tell everyone when the thing under it changes - on the GPU without\n // waiting for it in big scenes, so hovering never stalls a frame\n #updateHover() {\n this.#pickPending = false\n if (!this.#needsHover()) return\n const p = this.#pointer\n // what the keyboard stepped to is shown until the pointer moves\n if (this.#keyFocus) return this.#setHovered(this.#keyFocus, this.#keyAt(this.#keyFocus))\n if (this.#labelHover) return this.#setHovered(this.#labelHover)\n if (!p || this.#dragging) return this.#setHovered(null)\n const frame = this.#gpuFrame()\n if (frame && this.#hoverBusy) {\n // look again when the request out now lands\n this.#pickPending = true\n return\n }\n const request = frame ? this.renderer.pickAsync(frame, p.x, p.y) : undefined\n if (!request) return this.#setHovered(this.pick(p.x, p.y))\n this.#hoverBusy = true\n request.then((found) => {\n this.#hoverBusy = false\n if (this.#disposed) return\n // the pointer may have gone, or moved on (then a newer pick is due)\n this.#setHovered(this.#labelHover ?? (found && this.#pointer ? this.#exact(found, frame) : null))\n this.#schedule()\n })\n }\n\n /**\n * @param {Hit | null} hit\n * @param {{ clientX: number, clientY: number, event: PointerEvent | null } | null} [p] where it is shown - the pointer, or the keyboard's focus\n */\n #setHovered(hit, p = this.#pointer) {\n const before = this.#hovered\n // the same thing under the pointer: the same node, instance and row of data - a line's segments\n // and a surface's rows are told apart by their data, without a plain mesh changing per triangle\n const same = before === hit || (before && hit && before.node === hit.node && before.instance === hit.instance &&\n before.datum === hit.datum && (/** @type {any} */ (hit.node).drawMode !== 'points' || before.face === hit.face))\n this.#hovered = hit\n if (p && hit && this.#tooltip) this.#tooltip.show(hit, p.clientX, p.clientY)\n else this.#tooltip?.hide()\n if (same) return\n if (this.#highlightFor(before) || this.#highlightFor(hit) || this.#debugHovers()) this.invalidate()\n if (this.#handlers.click.size || this.lastFrame?.interactive) {\n this.canvas.style.cursor = hit && nearestAbove(hit.node, 'onDrag') ? 'grab' : hit && this.#clickable(hit) ? 'pointer' : ''\n }\n // node handlers: those that lose the pointer hear null, those that gain or keep it hear the hit\n const was = handlersAbove(before?.node, 'hover'), now = handlersAbove(hit?.node, 'hover')\n for (const fn of was) if (!now.includes(fn)) fn(null)\n for (const fn of now) fn(hit)\n for (const fn of this.#handlers.hover) fn(hit, p?.event ?? null)\n }\n\n /**\n * The pointer on a label that answers it: a click or hover there is one on what the label labels.\n * @param {'click' | 'over' | 'out'} type @param {import('./frame.js').FrameLabel} label @param {MouseEvent | null} e\n */\n #labelPointer(type, label, e) {\n const node = /** @type {any} */ (label.node), index = label.index\n const points = index !== null && node.drawMode === 'points'\n /** @type {Hit} */\n const hit = { node, point: label.position.clone(), distance: label.position.distanceTo(this.camera.worldPosition), normal: null,\n face: points ? index : null, instance: index !== null && !points ? index : null, uv: null, datum: node.datumAt?.(index) ?? null }\n if (type === 'click') {\n for (const fn of handlersAbove(node, 'click')) fn(hit)\n for (const fn of this.#handlers.click) fn(hit, e)\n return\n }\n this.#labelHover = type === 'over' ? hit : null\n if (e) {\n const rect = this.canvas.getBoundingClientRect()\n this.#pointer = { x: e.clientX - rect.left, y: e.clientY - rect.top, clientX: e.clientX, clientY: e.clientY, event: /** @type {PointerEvent} */ (e) }\n }\n if (type === 'out') this.#pointer = null\n this.#pickPending = true\n this.#schedule()\n }\n\n /** Does clicking this hit do anything? @param {Hit} hit */\n #clickable(hit) {\n return this.#handlers.click.size > 0 || handlersAbove(hit.node, 'click').length > 0\n }\n\n /** @param {Hit | null} hit @returns {FrameHighlight | null} */\n #highlightFor(hit) {\n if (!hit) return null\n // the nearest colour wins - or the nearest false, which tints nothing - and the nearest\n // highlightWhole is what is tinted as one\n let color = null, whole = null\n for (let n = /** @type {any} */ (hit.node); n; n = n.parent) {\n color ??= n.highlight\n whole ??= n.highlightWhole ? n : null\n }\n color ??= this.#highlight\n // the keyboard's focus always shows\n if (!color && hit === this.#keyFocus) color = FOCUS_COLOR\n if (!color) return null\n const node = /** @type {any} */ (hit.node)\n if (whole) {\n /** @type {Set<Node>} */\n const nodes = new Set()\n whole.traverse((n) => { nodes.add(n) })\n return { node, index: null, nodes, color, amount: HIGHLIGHT_AMOUNT }\n }\n const index = hit.instance ?? (node.drawMode === 'points' ? hit.face : null)\n return { node, index, color, amount: HIGHLIGHT_AMOUNT }\n }\n\n // hide labels that asked to be hidden behind geometry, by casting a ray to each\n /** @param {FrameDescription} frame */\n #occlude(frame) {\n const labels = /** @type {(import('./frame.js').FrameLabel & { occluded?: boolean })[]} */ (frame.labels)\n // a label waiting to be zoomed in to won't show either way, so it needs no ray\n const halfHeight = this.height / 2\n const testing = labels.filter((l) => l.style.occlude && l.visible && !(l.style.minScale && l.scale * halfHeight < l.style.minScale))\n if (!testing.length) return\n // what this frame drew hides what is behind it - the same surfaces the picture shows, each placed\n // once for all the rays, which ask only whether anything is nearer than their label\n const solids = Raycaster.solids([...frame.opaque, ...frame.transparent])\n const raycaster = new Raycaster()\n for (const label of testing) {\n raycaster.setFromCamera(label.ndc, this.camera)\n const distance = label.position.distanceTo(raycaster.ray.origin)\n // only solid surfaces hide labels, and not the instance or point being labelled\n label.occluded = raycaster.blocked(solids, distance * 0.995, label.node, label.index)\n }\n }\n\n #listen() {\n const canvas = this.canvas\n const at = (e) => {\n const rect = canvas.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top, clientX: e.clientX, clientY: e.clientY, event: e }\n }\n const move = (e) => {\n // the pointer takes over from the keyboard\n if (this.#keyFocus) this.#keyboard?.clear()\n this.#pointer = at(e)\n const press = this.#press\n if (press && press.id === e.pointerId && !press.moved && Math.hypot(this.#pointer.x - press.x, this.#pointer.y - press.y) >= DRAG_START) press.moved = true\n if (this.#drag) this.#moveDrag(e, this.#pointer)\n else this.#orbitPointer?.move(e)\n this.#dragging = e.buttons !== 0\n if (this.#dragging) this.#tooltip?.hide()\n else this.#tooltip?.move(e.clientX, e.clientY)\n if (!this.#needsHover()) return\n this.#pickPending = true\n this.#schedule()\n }\n const leave = () => {\n this.#pointer = null\n this.#pickPending = true\n this.#schedule()\n }\n const up = (e) => {\n if (this.#drag) this.#endDrag(e)\n else this.#orbitPointer?.up(e)\n this.#dragging = false\n this.#pickPending = true\n this.#schedule()\n }\n // every press starts here: on something with onDrag it drags that, anywhere else it orbits - and\n // one that moves far enough, either way, isn't a click\n const down = (e) => {\n // a new press replaces a drag whose letting go never arrived (released outside the window, say)\n if (this.#drag?.id === e.pointerId) return\n // and takes the camera from a glide\n this.#flight = null\n this.#drag = null\n const pressedAt = at(e)\n this.#press = { id: e.pointerId, x: pressedAt.x, y: pressedAt.y, moved: false }\n const hit = this.lastFrame?.draggable && !(e.pointerType === 'mouse' && e.button !== 0) ? this.pick(e) : null\n const node = hit && nearestAbove(hit.node, 'onDrag')\n if (!hit || !node) {\n this.#orbitPointer?.down(e)\n return\n }\n try { canvas.setPointerCapture(e.pointerId) } catch { /* drags still work inside the canvas */ }\n const p = at(e)\n const start = hit.point.clone()\n /** @type {import('./scene/Node.js').Drag} */\n const drag = { phase: 'start', hit, node, ray: this.rayAt(p.x, p.y), plane: { normal: new Vec3(0, 1, 0), point: start.clone() },\n start, point: start.clone(), delta: new Vec3(), event: e }\n this.#drag = { drag, id: e.pointerId, x: p.x, y: p.y, press: drag.ray, started: false }\n }\n const click = (e) => {\n // the end of a drag - of a node or of the orbit - isn't a click\n if (this.#press?.moved) {\n this.#press = null\n return\n }\n if (!this.#handlers.click.size && !this.lastFrame?.interactive) return\n const hit = this.pick(e)\n if (hit) for (const fn of handlersAbove(hit.node, 'click')) fn(hit)\n for (const fn of this.#handlers.click) fn(hit, e)\n }\n canvas.addEventListener('pointerdown', down)\n canvas.addEventListener('pointermove', move)\n canvas.addEventListener('pointerleave', leave)\n canvas.addEventListener('pointerup', up)\n canvas.addEventListener('pointercancel', up)\n canvas.addEventListener('click', click)\n const wheel = () => { this.#flight = null }\n canvas.addEventListener('wheel', wheel, { passive: true })\n this.#cleanup.push(() => {\n canvas.removeEventListener('wheel', wheel)\n canvas.removeEventListener('pointerdown', down)\n canvas.removeEventListener('pointermove', move)\n canvas.removeEventListener('pointerleave', leave)\n canvas.removeEventListener('pointerup', up)\n canvas.removeEventListener('pointercancel', up)\n canvas.removeEventListener('click', click)\n })\n\n if (typeof ResizeObserver !== 'undefined') {\n const resize = new ResizeObserver(() => {\n this.resize()\n // draw straight away: a resized canvas is blank until the next draw\n this.render()\n })\n resize.observe(canvas)\n this.#cleanup.push(() => resize.disconnect())\n }\n // the system's reduced-motion setting, followed as it changes\n const motion = globalThis.matchMedia?.('(prefers-reduced-motion: reduce)')\n if (motion) {\n const follow = () => {\n this.#systemReduced = motion.matches\n this.invalidate()\n }\n this.#systemReduced = motion.matches\n motion.addEventListener?.('change', follow)\n this.#cleanup.push(() => motion.removeEventListener?.('change', follow))\n }\n // an off-screen view (a dashboard tile scrolled away) does no work at all\n if (typeof IntersectionObserver !== 'undefined') {\n const visible = new IntersectionObserver(([entry]) => {\n this.#onScreen = entry.isIntersecting\n if (this.#onScreen) this.invalidate()\n })\n visible.observe(canvas)\n this.#cleanup.push(() => visible.disconnect())\n }\n }\n\n /**\n * The pointer moved while something is pressed: once it has moved far enough to be a drag, tell\n * the node's handler it started, then where it is on the plane each move.\n * @param {PointerEvent} e @param {{ x: number, y: number }} p\n */\n #moveDrag(e, p) {\n const d = this.#drag\n if (!d || e.pointerId !== d.id) return\n const { drag } = d\n drag.event = e\n drag.ray = this.rayAt(p.x, p.y)\n if (!d.started) {\n if (Math.hypot(p.x - d.x, p.y - d.y) < DRAG_START) return\n d.started = true\n this.canvas.style.cursor = 'grabbing'\n drag.phase = 'start'\n const plane = drag.plane\n drag.node.onDrag?.(drag)\n // a handler that chose another plane drags across that, from where the press meets it\n if (drag.plane !== plane || !drag.plane.point.equals(plane.point) || !drag.plane.normal.equals(plane.normal)) {\n drag.plane = { normal: Vec3.fromInput(drag.plane.normal, 'Drag').normalize(), point: Vec3.fromInput(drag.plane.point, 'Drag') }\n const t = d.press.intersectPlane(drag.plane.normal, drag.plane.point)\n if (t !== null) drag.start.copy(d.press.at(t))\n }\n }\n drag.phase = 'move'\n const t = drag.ray.intersectPlane(drag.plane.normal, drag.plane.point)\n if (t !== null) {\n drag.point = drag.ray.at(t)\n drag.delta.copy(drag.point).sub(drag.start)\n } else drag.point = null\n drag.node.onDrag?.(drag)\n this.invalidate()\n }\n\n /** The pointer let go: a drag ends, and the click that follows isn't one. @param {PointerEvent} e */\n #endDrag(e) {\n const d = this.#drag\n if (!d || e.pointerId !== d.id) return\n this.#drag = null\n try { this.canvas.releasePointerCapture(e.pointerId) } catch { /* already gone */ }\n if (!d.started) return\n d.drag.phase = 'end'\n d.drag.event = e\n d.drag.node.onDrag?.(d.drag)\n this.canvas.style.cursor = ''\n this.invalidate()\n }\n\n /** @param {FrameDescription} frame */\n #addAutoLights(frame) {\n if (!this.#noted) {\n this.#noted = true\n console.info('phoria2: the scene has no lights, so the View is lighting it (autoLight: false turns this off)')\n }\n const hemi = this.#autoSky, sun = this.#autoSun\n frame.lights.push(\n { kind: 'hemisphere', node: hemi, color: hemi.sky, ground: hemi.ground, intensity: hemi.intensity },\n { kind: 'directional', node: sun, color: sun.color, intensity: sun.intensity, direction: sun.worldDirection })\n }\n}\n\n/** Where a camera is and looks, to tell whether the app has moved it. @param {any} camera @returns {number[]} */\nfunction cameraPlace(camera) {\n return [...camera.position, ...(camera.target ?? []), camera.fov ?? camera.height]\n}\n/** @param {number[]} a @param {number[] | null} b */\nconst samePlace = (a, b) => !!b && a.length === b.length && a.every((v, i) => v === b[i])\n\n/** A box's eight corners - one point when it is a point. @param {Box3} box @returns {number[][]} */\nfunction corners(box) {\n if (box.isEmpty()) return []\n if (box.min.equals(box.max)) return [box.min.toArray()]\n const out = []\n for (let i = 0; i < 8; i++) out.push([i & 1 ? box.max[0] : box.min[0], i & 2 ? box.max[1] : box.min[1], i & 4 ? box.max[2] : box.min[2]])\n return out\n}\n\n// past this many instances or vertices, a drawable is fitted by the box round it all\nconst FIT_DETAIL = 4000\n\n/**\n * The points a camera draws of a subtree, to fit a view round: the corners of each thing's box, so\n * the empty space between things doesn't count as filled - and closer still, the corners of each\n * instance and the vertices of lines and points, so a cloud of them isn't fitted by the corners of\n * the cube round it.\n * @param {Node} node @param {Camera} camera @returns {number[][]}\n */\nfunction drawnPoints(node, camera) {\n node.updateWorld()\n /** @type {number[][]} */\n const points = []\n node.eachShownTo(camera, (n) => {\n const d = /** @type {any} */ (n)\n if ('instanceMatrices' in d && d.count <= FIT_DETAIL) {\n d.eachInstanceBox((x0, y0, z0, x1, y1, z1) => { points.push(...corners(new Box3([x0, y0, z0], [x1, y1, z1]))) })\n } else if ((d.drawMode === 'lines' || d.drawMode === 'points') && d.geometry.vertexCount <= FIT_DETAIL) {\n // the vertices drawn - every one, when indices pick them\n const g = d.geometry, p = g.positions, m = d.worldMatrix, count = g.indices ? g.vertexCount : g.drawnVertices\n for (let i = 0; i < count; i++) {\n const x = p[i * 3], y = p[i * 3 + 1], z = p[i * 3 + 2]\n points.push([m[0] * x + m[4] * y + m[8] * z + m[12], m[1] * x + m[5] * y + m[9] * z + m[13], m[2] * x + m[6] * y + m[10] * z + m[14]])\n }\n } else points.push(...corners(n.expandBounds(new Box3())))\n })\n return points\n}\n\n/** The nearest node at or above this one with a handler of this kind. @param {any} node @param {string} key */\nfunction nearestAbove(node, key) {\n for (let n = node; n; n = n.parent) if (n[key]) return n\n return null\n}\n\n/** @typedef {{ position: Vec3, target: Vec3, height?: number }} Place */\n/** @typedef {{ from: Place, to: Place, time: number, duration: number }} Flight */\n\n/** Where a camera is, and an orthographic one's view height. @param {any} cam @returns {Place} */\nfunction placeOf(cam) {\n return { position: cam.position.clone(), target: (cam.target ?? new Vec3()).clone(), height: cam.height }\n}\n\n/** @param {any} cam @param {Place} place */\nfunction setPlace(cam, place) {\n cam.position.copy(place.position)\n setTarget(cam, place.target)\n if (place.height !== undefined) cam.height = place.height\n}\n\n/** Move a camera's target, keeping the one it has. @param {any} cam @param {Vec3} target */\nfunction setTarget(cam, target) {\n if (cam.target) cam.target.copy(target)\n else cam.target = target.clone()\n}\n\n/**\n * Part way from one unit direction to another, along the great circle - by way of a side, when they\n * are opposite and every way round is as short.\n * @param {Vec3} a @param {Vec3} b @param {number} t\n * @returns {Vec3}\n */\nfunction turnBetween(a, b, t) {\n const cos = Math.max(-1, Math.min(1, a.dot(b)))\n if (cos > 0.9999) return a.clone().lerp(b, t).normalize()\n if (cos < -0.9999) {\n const side = Math.abs(a[1]) < 0.9 ? new Vec3(0, 1, 0) : new Vec3(1, 0, 0)\n const mid = a.clone().cross(side).normalize()\n return t < 0.5 ? turnBetween(a, mid, t * 2) : turnBetween(mid, b, t * 2 - 1)\n }\n const angle = Math.acos(cos), s = Math.sin(angle)\n return a.clone().multiplyScalar(Math.sin((1 - t) * angle) / s).add(b.clone().multiplyScalar(Math.sin(t * angle) / s))\n}\n\n/**\n * The handlers a label answers: those of a Label node that has its own, or those of the instance or\n * point it labels.\n * @param {import('./frame.js').FrameLabel} label @param {'hover' | 'click'} event @returns {Function[]}\n */\nfunction labelHandlers(label, event) {\n if (label.index === null && !label.node.handlersFor(event).length) return []\n return handlersAbove(label.node, event)\n}\n\n/**\n * A node's hover or click handlers and its ancestors', nearest first: each one's own, then its listeners.\n * @param {any} node @param {'hover' | 'click'} event @returns {Function[]}\n */\nfunction handlersAbove(node, event) {\n const list = []\n for (let n = node; n; n = n.parent) list.push(...n.handlersFor(event))\n return list\n}\n\n/** @param {HTMLCanvasElement | string | undefined} canvas @returns {HTMLCanvasElement} */\nfunction resolveCanvas(canvas) {\n if (canvas === undefined) {\n const c = document.createElement('canvas')\n Object.assign(c.style, { position: 'fixed', inset: '0', width: '100vw', height: '100vh', display: 'block' })\n document.body.append(c)\n return c\n }\n if (typeof canvas === 'string') {\n const el = document.querySelector(canvas)\n if (!el) fail('View', `canvas '${canvas}' not found`)\n if (!(el instanceof HTMLCanvasElement)) fail('View', `'${canvas}' is a <${el.tagName.toLowerCase()}>, not a <canvas>`)\n return el\n }\n if (!(canvas instanceof HTMLCanvasElement)) fail('View', `'canvas' must be a <canvas> element or a selector, got ${describe(canvas)}`)\n return canvas\n}\n\n/**\n * Debug options checked: true for everything but normals, false or null for none.\n * @param {boolean | DebugOptions | null} v\n * @returns {Required<DebugOptions> | null}\n */\nfunction debugOptions(v) {\n if (v === false || v === null) return null\n if (v === true) return { ...DEBUG_ALL }\n if (!v || typeof v !== 'object' || Array.isArray(v)) fail('View', `'debug' is true, false or { ${DEBUG_OPTIONS.join(', ')} }, got ${describe(v)}`)\n checkOptions('View', v, DEBUG_OPTIONS, { helpers: \"list what to draw: { lights: true, bounds: true, ... }\", fps: \"use 'stats: true'\", wireframe: \"use new Lines({ geometry: edges(geometry) }) for a wireframe\" }, 'debug')\n /** @type {any} */\n const o = {}\n for (const key of DEBUG_OPTIONS) {\n const value = /** @type {any} */ (v)[key]\n if (value === undefined) o[key] = false\n else if (key === 'bounds' || key === 'normals') o[key] = value === 'hovered' ? 'hovered' : checkBool(key, value, \"true, false or 'hovered'\")\n else if (key === 'stats') o[key] = value === true ? 'top-left' : value === false ? false : checkOneOf('View', 'debug.stats', value, CORNERS)\n else o[key] = checkBool(key, value, 'true or false')\n }\n return o\n}\n\n/** @param {string} key @param {unknown} v @param {string} expected */\nfunction checkBool(key, v, expected) {\n if (typeof v !== 'boolean') fail('View', `debug.${key} is ${expected}, got ${describe(v)}`)\n return v\n}\n","// Filling flat outlines with triangles: ear clipping, with holes bridged into the outline first so\n// the whole thing is one polygon. Plenty for the hand-made shapes extrude() takes - a few hundred\n// points - without a library.\n\n/** @typedef {[number, number]} Point2 */\n\n/** Twice the signed area: positive when the points run counter-clockwise. @param {Point2[]} points */\nexport function area(points) {\n let a = 0\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n a += (points[j][0] - points[i][0]) * (points[j][1] + points[i][1])\n }\n return a\n}\n\n/**\n * Triangles filling an outline with holes, as triples of indices into the outline's points\n * followed by each hole's, wound counter-clockwise. The outline may run either way round, and so\n * may the holes.\n * @param {Point2[]} outline\n * @param {Point2[][]} [holes]\n * @returns {number[]}\n */\nexport function triangulate(outline, holes = []) {\n // every point once, by index: the outline's, then each hole's in turn\n /** @type {Point2[]} */\n const points = [...outline]\n /** @type {number[]} */\n let ring = outline.map((_, i) => i)\n if (area(outline) < 0) ring.reverse()\n // holes go in clockwise, rightmost first, each bridged from its rightmost point\n const placed = holes.map((hole) => {\n const start = points.length\n points.push(...hole)\n const ids = hole.map((_, i) => start + i)\n if (area(hole) > 0) ids.reverse()\n return ids\n }).sort((a, b) => maxX(points, b) - maxX(points, a))\n for (const hole of placed) ring = bridge(points, ring, hole, placed)\n return clip(points, ring)\n}\n\n/** @param {Point2[]} points @param {number[]} ids */\nconst maxX = (points, ids) => Math.max(...ids.map((i) => points[i][0]))\n\n/**\n * Join a hole into the ring: from the hole's rightmost point to the nearest point of the ring it\n * can see, there and back, so the ring runs round the hole too.\n * @param {Point2[]} points @param {number[]} ring @param {number[]} hole @param {number[][]} holes\n * @returns {number[]}\n */\nfunction bridge(points, ring, hole, holes) {\n let m = 0\n hole.forEach((id, k) => { if (points[id][0] > points[hole[m]][0]) m = k })\n const M = points[hole[m]]\n // edges a bridge mustn't cross: the ring's and every hole's\n /** @type {[Point2, Point2][]} */\n const edges = []\n for (const ids of [ring, ...holes]) ids.forEach((id, k) => edges.push([points[id], points[ids[(k + 1) % ids.length]]]))\n let best = -1, bestD = Infinity\n ring.forEach((id, k) => {\n const P = points[id]\n const d = (P[0] - M[0]) ** 2 + (P[1] - M[1]) ** 2\n // nearer first, preferring points to the right as the usual bridge does\n const score = d * (P[0] >= M[0] ? 1 : 4)\n if (score >= bestD) return\n if (edges.some(([a, b]) => crosses(M, P, a, b))) return\n best = k\n bestD = score\n })\n if (best < 0) best = 0\n const around = [...hole.slice(m), ...hole.slice(0, m)]\n return [...ring.slice(0, best + 1), ...around, hole[m], ring[best], ...ring.slice(best + 1)]\n}\n\n/** Do segments pq and ab cross, other than at shared ends? @param {Point2} p @param {Point2} q @param {Point2} a @param {Point2} b */\nfunction crosses(p, q, a, b) {\n if (same(p, a) || same(p, b) || same(q, a) || same(q, b)) return false\n const d1 = cross(a, b, p), d2 = cross(a, b, q), d3 = cross(p, q, a), d4 = cross(p, q, b)\n return d1 * d2 < 0 && d3 * d4 < 0\n}\n\n/** @param {Point2} a @param {Point2} b */\nconst same = (a, b) => a[0] === b[0] && a[1] === b[1]\n\n/** Positive when a, b, c turn counter-clockwise. @param {Point2} a @param {Point2} b @param {Point2} c */\nconst cross = (a, b, c) => (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0])\n\n/**\n * Clip ears off a counter-clockwise ring until it is all triangles.\n * @param {Point2[]} points @param {number[]} ring\n * @returns {number[]}\n */\nfunction clip(points, ring) {\n const left = [...ring], out = []\n while (left.length > 3) {\n let cut = -1\n for (let k = 0; k < left.length && cut < 0; k++) if (isEar(points, left, k)) cut = k\n // nothing clean to cut (a sliver, or points that overlap): take the first convex corner, or any\n if (cut < 0) for (let k = 0; k < left.length && cut < 0; k++) if (convex(points, left, k)) cut = k\n if (cut < 0) cut = 0\n const n = left.length\n out.push(left[(cut + n - 1) % n], left[cut], left[(cut + 1) % n])\n left.splice(cut, 1)\n }\n if (left.length === 3) out.push(...left)\n return out\n}\n\n/** @param {Point2[]} points @param {number[]} left @param {number} k */\nfunction convex(points, left, k) {\n const n = left.length\n return cross(points[left[(k + n - 1) % n]], points[left[k]], points[left[(k + 1) % n]]) > 0\n}\n\n/** A convex corner with no other point inside its triangle. @param {Point2[]} points @param {number[]} left @param {number} k */\nfunction isEar(points, left, k) {\n if (!convex(points, left, k)) return false\n const n = left.length\n const a = points[left[(k + n - 1) % n]], b = points[left[k]], c = points[left[(k + 1) % n]]\n for (const id of left) {\n const p = points[id]\n if (same(p, a) || same(p, b) || same(p, c)) continue\n if (cross(a, b, p) >= 0 && cross(b, c, p) >= 0 && cross(c, a, p) >= 0) return false\n }\n return true\n}\n","// Geometry generators: plain functions returning a Geometry. Every shape follows the same\n// conventions - +Y up, counter-clockwise front faces, outward normals, glTF UVs (v down).\n\nimport { Geometry } from './Geometry.js'\nimport { area, triangulate } from './triangulate.js'\nimport { checkCount as count, checkLength as size, checkOneOf, describe, fail, resolveOptions as resolve } from '../validate.js'\n\nconst TAU = Math.PI * 2\n\n/** What each generator takes (a number alone sets the first, where that makes sense). */\nexport const GENERATOR_OPTIONS = {\n box: ['size', 'width', 'height', 'depth', 'segments'],\n sphere: ['radius', 'segments', 'rings'],\n plane: ['size', 'width', 'depth', 'segments'],\n cylinder: ['radius', 'radiusTop', 'height', 'segments', 'caps', 'axis'],\n torus: ['radius', 'tube', 'segments', 'tubeSegments'],\n icosphere: ['radius', 'detail'],\n lathe: ['points', 'segments', 'axis'],\n extrude: ['shape', 'holes', 'depth', 'axis'],\n axes: ['size'],\n grid: ['size', 'divisions'],\n}\n\n/**\n * @typedef {object} BoxOptions\n * @property {number} [size] sets width, height and depth together, default 1\n * @property {number} [width] along x, default size\n * @property {number} [height] along y, default size\n * @property {number} [depth] along z, default size\n * @property {number} [segments] subdivisions across each face, default 1\n */\n\n/**\n * @typedef {object} SphereOptions\n * @property {number} [radius] default 1\n * @property {number} [segments] around the Y axis, default 32\n * @property {number} [rings] from pole to pole, default 16\n */\n\n/**\n * @typedef {object} PlaneOptions\n * @property {number} [size] sets width and depth together, default 1\n * @property {number} [width] along x, default size\n * @property {number} [depth] along z, default size\n * @property {number} [segments] subdivisions along each side, default 1\n */\n\n/**\n * @typedef {object} CylinderOptions\n * @property {number} [radius] at the bottom, default 0.5\n * @property {number} [radiusTop] at the top, defaults to `radius`; 0 gives a cone\n * @property {number} [height] along y, default 1\n * @property {number} [segments] around the Y axis, default 32\n * @property {boolean} [caps] close the ends, default true\n * @property {Axis} [axis] the axis it runs along, default 'y'\n */\n\n/**\n * @typedef {object} TorusOptions\n * @property {number} [radius] from the centre to the middle of the tube, default 1\n * @property {number} [tube] radius of the tube, default 0.4\n * @property {number} [segments] around the ring, default 48\n * @property {number} [tubeSegments] around the tube, default 16\n */\n\n/**\n * @typedef {object} IcosphereOptions\n * @property {number} [radius] default 1\n * @property {number} [detail] subdivision level 0-6, default 2; 0 is an icosahedron (20 faces)\n */\n\n/**\n * @typedef {object} LatheOptions\n * @property {ArrayLike<number>[]} points the profile, as [radius, y] pairs from the bottom up - the\n * outside of the surface is on the right as you go up it\n * @property {number} [segments] around the axis, default 32\n * @property {Axis} [axis] the axis it is turned about, default 'y'\n */\n\n/**\n * @typedef {object} ExtrudeOptions\n * @property {ArrayLike<number>[]} shape the outline, as [x, y] pairs, either way round\n * @property {ArrayLike<number>[][]} [holes] outlines cut out of it, each as [x, y] pairs\n * @property {number} [depth] along the axis, default 1\n * @property {Axis} [axis] the axis it is pushed along, default 'z'; the outline is drawn as seen\n * looking back down the axis from its + end, with y up ('y': seen from above, y away from you)\n */\n\n/** @typedef {'x' | 'y' | 'z'} Axis */\n\n/**\n * @typedef {object} AxesOptions\n * @property {number} [size] length of each axis line, default 1\n */\n\n// three.js names people will reach for, mapped to what to use here\nconst SEGMENT_HINT = \"has one 'segments' option, used for every face\"\n\n/**\n * A box centred on the origin. Each face has its own 4+ vertices so normals and UVs are per face;\n * seen from outside, a face's top left has uv (0, 0). Side faces keep +Y up.\n * @example box(2) // 2 x 2 x 2\n * @example box({ width: 2, height: 1, depth: 0.5, segments: 4 })\n * @param {number | BoxOptions} [options] a number sets width, height and depth\n * @returns {Geometry}\n */\nexport function box(options) {\n const owner = 'box()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.box, (n) => ({ size: n }), {\n widthSegments: `box() ${SEGMENT_HINT}`,\n heightSegments: `box() ${SEGMENT_HINT}`,\n depthSegments: `box() ${SEGMENT_HINT}`,\n })\n // size sets all three; width, height and depth override it per axis\n const all = size(owner, 'size', o.size, 1)\n const width = size(owner, 'width', o.width, all)\n const height = size(owner, 'height', o.height, all)\n const depth = size(owner, 'depth', o.depth, all)\n const segments = count(owner, 'segments', o.segments, 1)\n const scale = [width, height, depth]\n const m = new Builder()\n for (const [n, right, up] of BOX_FACES) {\n const start = m.count\n for (let j = 0; j <= segments; j++) {\n const v = j / segments\n for (let i = 0; i <= segments; i++) {\n const u = i / segments\n const p = [0, 1, 2].map((k) => (n[k] * 0.5 + right[k] * (u - 0.5) + up[k] * (0.5 - v)) * scale[k])\n m.vertex(p[0], p[1], p[2], n[0], n[1], n[2], u, v)\n }\n }\n m.grid(start, segments, segments)\n }\n return m.build({ type: 'box', width, height, depth, segments })\n}\n\n// [normal, right (u grows), up (v shrinks)] per face, with right x up = normal so faces wind CCW\nconst BOX_FACES = [\n [[1, 0, 0], [0, 0, -1], [0, 1, 0]],\n [[-1, 0, 0], [0, 0, 1], [0, 1, 0]],\n [[0, 1, 0], [1, 0, 0], [0, 0, -1]],\n [[0, -1, 0], [1, 0, 0], [0, 0, 1]],\n [[0, 0, 1], [1, 0, 0], [0, 1, 0]],\n [[0, 0, -1], [-1, 0, 0], [0, 1, 0]],\n]\n\n/**\n * A UV sphere centred on the origin. u runs once around (with a seam column of repeated vertices\n * so the texture can wrap), v from the north pole (0) to the south pole (1).\n * @example sphere(2)\n * @example sphere({ radius: 1, segments: 64, rings: 32 })\n * @param {number | SphereOptions} [options] a number sets the radius\n * @returns {Geometry}\n */\nexport function sphere(options) {\n const owner = 'sphere()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.sphere, (n) => ({ radius: n }), {\n widthSegments: \"sphere(): use 'segments' for the divisions around the sphere\",\n heightSegments: \"sphere(): use 'rings' for the divisions from pole to pole\",\n })\n const radius = size(owner, 'radius', o.radius, 1)\n const segments = count(owner, 'segments', o.segments, 32, 3)\n const rings = count(owner, 'rings', o.rings, 16, 2)\n const m = new Builder()\n for (let j = 0; j <= rings; j++) {\n const v = j / rings\n const pole = j === 0 || j === rings\n // exact poles, so they sit on the axis and weld in edges()\n const sinT = pole ? 0 : Math.sin(v * Math.PI)\n const cosT = j === 0 ? 1 : j === rings ? -1 : Math.cos(v * Math.PI)\n for (let i = 0; i <= segments; i++) {\n // a pole vertex serves only the triangle to its right, so centre its u over that triangle\n const u = pole && i < segments ? (i + 0.5) / segments : i / segments\n const phi = ((i % segments) / segments) * TAU // the seam column repeats column 0 exactly\n const nx = -Math.cos(phi) * sinT, ny = cosT, nz = Math.sin(phi) * sinT\n m.vertex(nx * radius, ny * radius, nz * radius, nx, ny, nz, u, v)\n }\n }\n m.grid(0, segments, rings, { pinchTop: true, pinchBottom: true })\n return m.build({ type: 'sphere', radius, segments, rings })\n}\n\n/**\n * A flat rectangle in the x-z plane, centred on the origin and facing +Y. Seen from above, the\n * -x, -z corner has uv (0, 0) and the +x, +z corner (1, 1).\n * @example plane(10)\n * @example plane({ width: 4, depth: 2, segments: 8 })\n * @param {number | PlaneOptions} [options] a number sets width and depth\n * @returns {Geometry}\n */\nexport function plane(options) {\n const owner = 'plane()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.plane, (n) => ({ size: n }), {\n height: \"plane() lies in the x-z plane - use 'depth' rather than 'height'\",\n widthSegments: `plane() ${SEGMENT_HINT}`,\n heightSegments: `plane() ${SEGMENT_HINT}`,\n })\n const all = size(owner, 'size', o.size, 1)\n const width = size(owner, 'width', o.width, all)\n const depth = size(owner, 'depth', o.depth, all)\n const segments = count(owner, 'segments', o.segments, 1)\n const m = new Builder()\n for (let j = 0; j <= segments; j++) {\n const v = j / segments\n for (let i = 0; i <= segments; i++) {\n const u = i / segments\n m.vertex((u - 0.5) * width, 0, (v - 0.5) * depth, 0, 1, 0, u, v)\n }\n }\n m.grid(0, segments, segments)\n return m.build({ type: 'plane', width, depth, segments })\n}\n\n/**\n * A cylinder along the Y axis (or `axis`), centred on the origin; `radiusTop: 0` makes a cone. The\n * side and the caps have separate vertices so both get the right normals. u runs around the side\n * from +Z.\n * @example cylinder({ radius: 0.5, height: 2 })\n * @example cylinder({ radius: 1, radiusTop: 0 }) // a cone\n * @example cylinder({ radius: 0.1, height: 3, axis: 'x' }) // an axle lying along x\n * @param {CylinderOptions} [options]\n * @returns {Geometry}\n */\nexport function cylinder(options) {\n const owner = 'cylinder()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.cylinder, null, {\n radiusBottom: \"cylinder(): use 'radius' for the bottom radius\",\n radialSegments: \"cylinder(): use 'segments' for the divisions around the cylinder\",\n openEnded: \"cylinder(): use 'caps: false' for an open tube\",\n })\n const radius = size(owner, 'radius', o.radius, 0.5, true)\n const radiusTop = size(owner, 'radiusTop', o.radiusTop, radius, true)\n if (radius === 0 && radiusTop === 0) fail(owner, \"'radius' and 'radiusTop' can't both be 0\")\n const height = size(owner, 'height', o.height, 1)\n const segments = count(owner, 'segments', o.segments, 32, 3)\n const caps = o.caps ?? true\n if (typeof caps !== 'boolean') fail(owner, `'caps' must be true or false, got ${describe(caps)}`)\n const axis = axisOf(owner, o.axis, 'y')\n\n const m = new Builder()\n // side normals lean up as the side narrows towards the top\n const slope = radius - radiusTop, len = Math.hypot(height, slope)\n const out = height / len, ny = slope / len\n for (let j = 0; j <= 1; j++) {\n const r = j === 0 ? radiusTop : radius\n const y = j === 0 ? height / 2 : -height / 2\n for (let i = 0; i <= segments; i++) {\n // a cone's tip, like a sphere's pole, serves one triangle - centre its u and normal on it\n const u = r === 0 && i < segments ? (i + 0.5) / segments : i / segments\n const phi = r === 0 ? u * TAU : ((i % segments) / segments) * TAU\n const s = Math.sin(phi), c = Math.cos(phi)\n m.vertex(r * s, y, r * c, out * s, ny, out * c, u, j)\n }\n }\n m.grid(0, segments, 1, { pinchTop: radiusTop === 0, pinchBottom: radius === 0 })\n if (caps) {\n if (radiusTop > 0) cap(m, radiusTop, height / 2, 1, segments)\n if (radius > 0) cap(m, radius, -height / 2, -1, segments)\n }\n m.turn('y', axis)\n return m.build({ type: 'cylinder', radius, radiusTop, height, segments, caps, ...(axis !== 'y' && { axis }) })\n}\n\n/**\n * A disc closing one end of a cylinder: a centre vertex plus a ring. UVs map the disc into the\n * unit square the way a box's top and bottom faces are mapped.\n * @param {Builder} m @param {number} radius @param {number} y @param {1 | -1} side +1 top, -1 bottom\n * @param {number} segments\n */\nfunction cap(m, radius, y, side, segments) {\n const centre = m.vertex(0, y, 0, 0, side, 0, 0.5, 0.5)\n for (let i = 0; i < segments; i++) {\n const phi = (i / segments) * TAU, s = Math.sin(phi), c = Math.cos(phi)\n // seen from outside the top cap has -z up and the bottom cap +z up\n m.vertex(radius * s, y, radius * c, 0, side, 0, 0.5 + s / 2, 0.5 + (side * c) / 2)\n }\n for (let i = 0; i < segments; i++) {\n const a = centre + 1 + i, b = centre + 1 + ((i + 1) % segments)\n // the ring turns counter-clockwise seen from +Y, so the bottom cap reverses it\n if (side > 0) m.indices.push(centre, a, b)\n else m.indices.push(centre, b, a)\n }\n}\n\n/**\n * A torus lying in the x-z plane (the ring goes around the Y axis), centred on the origin.\n * u runs around the ring from +Z, v around the tube starting at its outer edge and heading down.\n * @example torus({ radius: 1, tube: 0.25 })\n * @param {TorusOptions} [options]\n * @returns {Geometry}\n */\nexport function torus(options) {\n const owner = 'torus()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.torus, null, {\n tubularSegments: \"torus(): use 'segments' for the divisions around the ring\",\n radialSegments: \"torus(): use 'tubeSegments' for the divisions around the tube\",\n })\n const radius = size(owner, 'radius', o.radius, 1)\n const tube = size(owner, 'tube', o.tube, 0.4)\n const segments = count(owner, 'segments', o.segments, 48, 3)\n const tubeSegments = count(owner, 'tubeSegments', o.tubeSegments, 16, 3)\n const m = new Builder()\n for (let j = 0; j <= tubeSegments; j++) {\n const v = j / tubeSegments\n // negative angle so v heads down the outside first, keeping the winding counter-clockwise\n const theta = -((j % tubeSegments) / tubeSegments) * TAU\n const ct = Math.cos(theta), st = Math.sin(theta)\n for (let i = 0; i <= segments; i++) {\n const u = i / segments\n const phi = ((i % segments) / segments) * TAU\n const dx = Math.sin(phi), dz = Math.cos(phi)\n const nx = ct * dx, ny = st, nz = ct * dz\n m.vertex(radius * dx + tube * nx, tube * ny, radius * dz + tube * nz, nx, ny, nz, u, v)\n }\n }\n m.grid(0, segments, tubeSegments)\n return m.build({ type: 'torus', radius, tube, segments, tubeSegments })\n}\n\n/**\n * A sphere made by subdividing an icosahedron - evenly spread triangles, no poles. Vertices are\n * shared, so it is smooth shaded; it has no UVs (use sphere() for texturing).\n * @example icosphere({ radius: 1, detail: 3 })\n * @param {number | IcosphereOptions} [options] a number sets the radius\n * @returns {Geometry}\n */\nexport function icosphere(options) {\n const owner = 'icosphere()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.icosphere, (n) => ({ radius: n }), {\n subdivisions: \"icosphere(): use 'detail' (0-6) for the subdivision level\",\n })\n const radius = size(owner, 'radius', o.radius, 1)\n const detail = count(owner, 'detail', o.detail, 2, 0, 6)\n\n const t = (1 + Math.sqrt(5)) / 2\n /** @type {number[]} unit-length directions */\n const dirs = []\n const add = (x, y, z) => {\n const l = Math.hypot(x, y, z)\n dirs.push(x / l, y / l, z / l)\n return dirs.length / 3 - 1\n }\n for (const [x, y, z] of [\n [-1, t, 0], [1, t, 0], [-1, -t, 0], [1, -t, 0], [0, -1, t], [0, 1, t],\n [0, -1, -t], [0, 1, -t], [t, 0, -1], [t, 0, 1], [-t, 0, -1], [-t, 0, 1],\n ]) add(x, y, z)\n let faces = [\n 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1,\n ]\n for (let level = 0; level < detail; level++) {\n // each edge's midpoint is made once and shared by the two triangles either side\n /** @type {Map<number, number>} */\n const midpoints = new Map()\n const mid = (a, b) => {\n const key = a < b ? a * 65536 + b : b * 65536 + a\n let m = midpoints.get(key)\n if (m === undefined) {\n m = add(dirs[a * 3] + dirs[b * 3], dirs[a * 3 + 1] + dirs[b * 3 + 1], dirs[a * 3 + 2] + dirs[b * 3 + 2])\n midpoints.set(key, m)\n }\n return m\n }\n const next = []\n for (let f = 0; f < faces.length; f += 3) {\n const a = faces[f], b = faces[f + 1], c = faces[f + 2]\n const ab = mid(a, b), bc = mid(b, c), ca = mid(c, a)\n next.push(a, ab, ca, ab, b, bc, ca, bc, c, ab, bc, ca)\n }\n faces = next\n }\n const g = new Geometry({ positions: dirs.map((d) => d * radius), normals: dirs, indices: faces })\n g.source = { type: 'icosphere', radius, detail }\n return g\n}\n\n/**\n * A profile turned about the Y axis (or `axis`, with y up the profile becoming that axis), as on a\n * lathe: pistons, bottles, bolts, vases, pulleys. Corners sharper\n * than about 30 degrees stay sharp; gentler ones are shaded smooth. A profile that starts or ends\n * on the axis (radius 0) closes over it. u runs around from +Z and v along the profile from its\n * last point to its first - top to bottom, as on cylinder().\n * @example lathe({ points: [[0, 0], [1, 0], [1, 2], [0.6, 2.4], [0, 2.4]] }) // a closed can with a shoulder\n * @example lathe({ points: outline.arc({ radius: 1, from: -Math.PI / 2, to: Math.PI / 2 }), axis: 'x' }) // a ball on an x axle\n * @param {LatheOptions} options\n * @returns {Geometry}\n */\nexport function lathe(options) {\n const owner = 'lathe()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.lathe, null, {\n divisions: \"lathe(): use 'segments' for the divisions around the axis\",\n phiSegments: \"lathe(): use 'segments' for the divisions around the axis\",\n profile: \"lathe(): use 'points' for the profile, as [radius, y] pairs\",\n })\n // a radius a hair off the axis (an arc's end, from cos(pi / 2)) is on it, so the shape closes there\n const points = pairs(owner, 'points', o.points, 2).map(([r, y]) => /** @type {[number, number]} */ ([Math.abs(r) < 1e-9 ? 0 : r, y]))\n if (points.some(([r]) => r < 0)) fail(owner, \"'points' are [radius, y] pairs - a radius can't be below 0\")\n const segments = count(owner, 'segments', o.segments, 32, 3)\n const axis = axisOf(owner, o.axis, 'y')\n\n // each span of the profile, with its outward normal (to the right, going up)\n const spans = []\n for (let k = 0; k + 1 < points.length; k++) {\n const [r0, y0] = points[k], [r1, y1] = points[k + 1]\n const len = Math.hypot(r1 - r0, y1 - y0)\n if (len === 0) continue\n spans.push({ from: points[k], to: points[k + 1], len, normal: [(y1 - y0) / len, -(r1 - r0) / len] })\n }\n if (!spans.length) fail(owner, \"'points' need at least two different points\")\n const total = spans.reduce((t, s) => t + s.len, 0)\n const m = new Builder()\n let along = 0\n spans.forEach((s, k) => {\n const start = smoothed(spans[k - 1]?.normal, s.normal), end = smoothed(spans[k + 1]?.normal, s.normal)\n const first = m.count\n // the far end first, as cylinder() puts its top row first, so the winding faces out\n for (const [[r, y], [nr, ny], v] of [[s.to, end, 1 - (along + s.len) / total], [s.from, start, 1 - along / total]]) {\n for (let i = 0; i <= segments; i++) {\n const phi = ((i % segments) / segments) * TAU, sin = Math.sin(phi), cos = Math.cos(phi)\n m.vertex(r * sin, y, r * cos, nr * sin, ny, nr * cos, i / segments, v)\n }\n }\n m.grid(first, segments, 1, { pinchTop: s.to[0] === 0, pinchBottom: s.from[0] === 0 })\n along += s.len\n })\n m.turn('y', axis)\n return m.build({ type: 'lathe', points: points.map((p) => [...p]), segments, ...(axis !== 'y' && { axis }) })\n}\n\n/**\n * A flat outline pushed out along Z (or `axis`), centred on the origin: the front faces +Z, the\n * back -Z, and the sides follow the outline. With another axis the front faces that axis's + end,\n * the outline drawn as seen from there. Concave outlines and holes are fine. Corners sharper than about 30\n * degrees stay sharp; gentler ones are shaded smooth, so a many-sided circle looks round. On the\n * front and back u, v span the outline's bounds, upright as seen from that side; on the sides u\n * runs round each outline and v from front to back.\n * @example extrude({ shape: [[0, 0], [2, 0], [2, 1], [0, 1]], depth: 0.5 })\n * @example extrude({ shape: outline.rect(2), holes: [outline.circle(0.5)], depth: 0.2 }) // a plate with a hole\n * @example extrude({ shape: outline.gear({ radius: 1, teeth: 40 }), depth: 0.1, axis: 'x' }) // a gear on an x axle\n * @param {ExtrudeOptions} options\n * @returns {Geometry}\n */\nexport function extrude(options) {\n const owner = 'extrude()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.extrude, null, {\n amount: \"extrude(): use 'depth'\",\n points: \"extrude(): use 'shape' for the outline, as [x, y] pairs\",\n outline: \"extrude(): use 'shape' for the outline, as [x, y] pairs\",\n bevelEnabled: \"extrude() has no bevel - round the shape's corners instead\",\n })\n const shape = withoutRepeats(pairs(owner, 'shape', o.shape, 3))\n if (o.holes !== undefined && !Array.isArray(o.holes)) fail(owner, `'holes' must be a list of outlines, got ${describe(o.holes)}`)\n if (typeof o.holes?.[0]?.[0] === 'number') fail(owner, \"'holes' is a list of outlines - for one hole, holes: [outline]\")\n const holes = /** @type {unknown[]} */ (o.holes ?? []).map((h, i) => withoutRepeats(pairs(owner, `holes[${i}]`, h, 3)))\n const depth = size(owner, 'depth', o.depth, 1)\n const axis = axisOf(owner, o.axis, 'z')\n const front = depth / 2\n\n // the outline counter-clockwise and the holes clockwise, so every side faces out of the solid\n const outline = area(shape) < 0 ? [...shape].reverse() : shape\n const cutouts = holes.map((h) => (area(h) > 0 ? [...h].reverse() : h))\n const all = [outline, ...cutouts].flat()\n let x0 = Infinity, x1 = -Infinity, y0 = Infinity, y1 = -Infinity\n for (const [x, y] of all) {\n x0 = Math.min(x0, x)\n x1 = Math.max(x1, x)\n y0 = Math.min(y0, y)\n y1 = Math.max(y1, y)\n }\n const w = x1 - x0 || 1, h = y1 - y0 || 1\n\n const m = new Builder()\n // front and back, from one triangulation\n const tris = triangulate(outline, cutouts)\n for (const [z, nz] of [[front, 1], [-front, -1]]) {\n const start = m.count\n // the back is mapped as seen from behind, as box() maps its back face\n for (const [x, y] of all) m.vertex(x, y, z, 0, 0, nz, nz > 0 ? (x - x0) / w : (x1 - x) / w, (y1 - y) / h)\n for (let t = 0; t < tris.length; t += 3) {\n if (nz > 0) m.indices.push(start + tris[t], start + tris[t + 1], start + tris[t + 2])\n else m.indices.push(start + tris[t], start + tris[t + 2], start + tris[t + 1])\n }\n }\n // the sides: a quad per edge, sharing normals with the next edge across a gentle corner\n for (const ring of [outline, ...cutouts]) {\n const n = ring.length\n const lengths = ring.map(([ax, ay], i) => Math.hypot(ring[(i + 1) % n][0] - ax, ring[(i + 1) % n][1] - ay))\n const normals = ring.map(([ax, ay], i) => {\n const [bx, by] = ring[(i + 1) % n], l = lengths[i] || 1\n return /** @type {[number, number]} */ ([(by - ay) / l, -(bx - ax) / l])\n })\n const perimeter = lengths.reduce((t, l) => t + l, 0) || 1\n let along = 0\n for (let i = 0; i < n; i++) {\n const own = normals[i]\n const [na, nb] = [smoothed(normals[(i + n - 1) % n], own), smoothed(normals[(i + 1) % n], own)]\n const [ax, ay] = ring[i], [bx, by] = ring[(i + 1) % n]\n const u0 = along / perimeter, u1 = (along + lengths[i]) / perimeter\n const a = m.vertex(ax, ay, front, na[0], na[1], 0, u0, 0)\n const b = m.vertex(ax, ay, -front, na[0], na[1], 0, u0, 1)\n const c = m.vertex(bx, by, -front, nb[0], nb[1], 0, u1, 1)\n const d = m.vertex(bx, by, front, nb[0], nb[1], 0, u1, 0)\n m.indices.push(a, b, c, a, c, d)\n along += lengths[i]\n }\n }\n m.turn('z', axis)\n return m.build({ type: 'extrude', shape: shape.map((p) => [...p]), holes: holes.map((hole) => hole.map((p) => [...p])), depth, ...(axis !== 'z' && { axis }) })\n}\n\n// corners turning less than this (about 30 degrees) are shaded smooth\nconst CREASE = Math.cos(Math.PI / 6)\n\n/**\n * A 2D normal where a span meets its neighbour: the two averaged across a gentle corner, its own at\n * a sharp one (or at an end, with no neighbour).\n * @param {number[] | undefined} other @param {number[]} own\n * @returns {number[]}\n */\nfunction smoothed(other, own) {\n if (!other || other[0] * own[0] + other[1] * own[1] < CREASE) return own\n const x = other[0] + own[0], y = other[1] + own[1], l = Math.hypot(x, y) || 1\n return [x / l, y / l]\n}\n\n/**\n * A list of [a, b] number pairs, at least `min` long.\n * @param {string} owner @param {string} name @param {unknown} value @param {number} min\n * @returns {[number, number][]}\n */\nfunction pairs(owner, name, value, min) {\n if (!Array.isArray(value)) fail(owner, `'${name}' must be a list of [x, y] pairs, got ${describe(value)}`)\n const list = /** @type {any[]} */ (value)\n if (list.length < min) fail(owner, `'${name}' needs at least ${min} points, got ${list.length}`)\n return list.map((p, i) => {\n if (!p || typeof p !== 'object' || typeof p.length !== 'number' || p.length < 2) {\n fail(owner, `'${name}' must be a list of [x, y] pairs - point ${i} is ${describe(p)}`)\n }\n const a = p[0], b = p[1]\n if (typeof a !== 'number' || typeof b !== 'number' || !Number.isFinite(a) || !Number.isFinite(b)) {\n fail(owner, `'${name}' point ${i} must be two finite numbers, got ${describe(p)}`)\n }\n return /** @type {[number, number]} */ ([a, b])\n })\n}\n\n/**\n * Line geometry outlining a mesh: one vertex pair per edge, for drawing as Lines. Edges shared by\n * two faces that are flat to each other (within `angle` degrees - 1 unless given) are left out, so a\n * box gives its 12 outline edges rather than its triangle diagonals. A larger angle leaves out the\n * facets of round surfaces too - 30 draws a cylinder's rims but not the lines down its side, as a\n * drawing does. Vertices at exactly the same position are merged first, so meshes with separate\n * vertices per face (box()) still share their edges.\n * @example new Lines({ geometry: edges(box()) })\n * @example new Lines({ geometry: edges(cylinder({ segments: 48 }), { angle: 30 }) }) // just the rims\n * @param {Geometry} geometry triangles, indexed or not\n * @param {{ angle?: number }} [options] how far, in degrees, two faces must turn from each other to make an edge (default 1)\n * @returns {Geometry}\n */\nexport function edges(geometry, options = {}) {\n if (!(geometry instanceof Geometry)) fail('edges()', `expected a Geometry, got ${describe(geometry)}`)\n const { angle = 1 } = resolve('edges()', options, ['angle'], null)\n if (!(angle >= 0 && angle < 180)) fail('edges()', `'angle' is in degrees, 0 to under 180, got ${describe(angle)}`)\n const flat = Math.cos((angle * Math.PI) / 180)\n const p = geometry.positions, index = geometry.indices, n = geometry.vertexCount\n // weld: map each vertex to the first vertex at the same position\n /** @type {Map<string, number>} */\n const seen = new Map()\n const weld = new Uint32Array(n)\n for (let i = 0; i < n; i++) {\n const key = `${p[i * 3]},${p[i * 3 + 1]},${p[i * 3 + 2]}`\n let w = seen.get(key)\n if (w === undefined) seen.set(key, w = i)\n weld[i] = w\n }\n\n /** @type {Map<number, { a: number, b: number, nx: number, ny: number, nz: number, faces: number, crease: boolean }>} */\n const found = new Map()\n const corners = index ? index.length : n\n for (let t = 0; t + 2 < corners; t += 3) {\n const a = weld[index ? index[t] : t], b = weld[index ? index[t + 1] : t + 1], c = weld[index ? index[t + 2] : t + 2]\n const abx = p[b * 3] - p[a * 3], aby = p[b * 3 + 1] - p[a * 3 + 1], abz = p[b * 3 + 2] - p[a * 3 + 2]\n const acx = p[c * 3] - p[a * 3], acy = p[c * 3 + 1] - p[a * 3 + 1], acz = p[c * 3 + 2] - p[a * 3 + 2]\n let nx = aby * acz - abz * acy, ny = abz * acx - abx * acz, nz = abx * acy - aby * acx\n const len = Math.hypot(nx, ny, nz)\n if (len === 0) continue // degenerate: no faces to compare, nothing to outline\n nx /= len\n ny /= len\n nz /= len\n for (const [v0, v1] of [[a, b], [b, c], [c, a]]) {\n const lo = Math.min(v0, v1), hi = Math.max(v0, v1)\n const key = lo * n + hi\n const e = found.get(key)\n if (!e) found.set(key, { a: lo, b: hi, nx, ny, nz, faces: 1, crease: false })\n else {\n e.faces++\n if (e.nx * nx + e.ny * ny + e.nz * nz < flat) e.crease = true\n }\n }\n }\n\n // keep open edges and creases; compact to just the vertices they use\n /** @type {Map<number, number>} */\n const remap = new Map()\n /** @type {number[]} */\n const positions = []\n /** @type {number[]} */\n const indices = []\n const use = (v) => {\n let i = remap.get(v)\n if (i === undefined) {\n remap.set(v, i = positions.length / 3)\n positions.push(p[v * 3], p[v * 3 + 1], p[v * 3 + 2])\n }\n return i\n }\n for (const e of found.values()) {\n if (e.faces === 1 || e.crease) indices.push(use(e.a), use(e.b))\n }\n return new Geometry({ positions, indices })\n}\n\n/**\n * Line geometry for the three axes: from the origin along +X (red), +Y (green) and +Z (blue).\n * Draw with Lines and `vertexColors: true`.\n * @example new Lines({ geometry: axes(2), material: new LineMaterial({ vertexColors: true }) })\n * @param {number | AxesOptions} [options] a number sets the size\n * @returns {Geometry}\n */\nexport function axes(options) {\n const owner = 'axes()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.axes, (n) => ({ size: n }))\n const s = size(owner, 'size', o.size, 1)\n const g = new Geometry({\n positions: [0, 0, 0, s, 0, 0, 0, 0, 0, 0, s, 0, 0, 0, 0, 0, 0, s],\n colors: [1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1],\n })\n g.source = { type: 'axes', size: s }\n return g\n}\n\n/**\n * A square grid of lines in the x-z plane, centred on the origin - draw it with Lines. (A plane's\n * edges() would only give its outline, since edges() drops lines between flat faces.)\n * @example new Lines({ geometry: grid({ size: 10, divisions: 10 }), material: { color: '#999' } })\n * @param {number | { size?: number, divisions?: number }} [options] a number sets the size\n * @returns {Geometry}\n */\nexport function grid(options) {\n const owner = 'grid()'\n const o = resolve(owner, options, GENERATOR_OPTIONS.grid, (n) => ({ size: n }), {\n segments: \"grid() uses 'divisions' for the number of squares along each side\",\n })\n const s = size(owner, 'size', o.size, 10)\n const divisions = count(owner, 'divisions', o.divisions, 10)\n const half = s / 2\n /** @type {number[]} */\n const positions = []\n for (let i = 0; i <= divisions; i++) {\n const p = -half + (s * i) / divisions\n positions.push(p, 0, -half, p, 0, half, -half, 0, p, half, 0, p)\n }\n const g = new Geometry({ positions })\n g.source = { type: 'grid', size: s, divisions }\n return g\n}\n\n// Collects vertex data for the analytic shapes, which supply their own normals and UVs.\nclass Builder {\n /** @type {number[]} */ positions = []\n /** @type {number[]} */ normals = []\n /** @type {number[]} */ uvs = []\n /** @type {number[]} */ indices = []\n\n get count() {\n return this.positions.length / 3\n }\n\n /**\n * @param {number} x @param {number} y @param {number} z\n * @param {number} nx @param {number} ny @param {number} nz\n * @param {number} u @param {number} v\n * @returns {number} the new vertex's index\n */\n vertex(x, y, z, nx, ny, nz, u, v) {\n this.positions.push(x, y, z)\n this.normals.push(nx, ny, nz)\n this.uvs.push(u, v)\n return this.count - 1\n }\n\n /**\n * Triangulate a grid of (cols + 1) x (rows + 1) vertices added row by row from `start`: top row\n * first, u growing along each row, as seen from the front. Each cell becomes two triangles\n * wound counter-clockwise from the front. A pinched row is a single point (a pole or a cone's\n * tip), where one triangle per cell is enough and the other would have no area.\n * @param {number} start @param {number} cols @param {number} rows\n * @param {{ pinchTop?: boolean, pinchBottom?: boolean }} [pinch]\n */\n grid(start, cols, rows, { pinchTop = false, pinchBottom = false } = {}) {\n const stride = cols + 1\n for (let j = 0; j < rows; j++) {\n for (let i = 0; i < cols; i++) {\n const a = start + j * stride + i // top left\n const b = a + stride // bottom left\n const c = b + 1 // bottom right\n const d = a + 1 // top right\n if (!(pinchBottom && j === rows - 1)) this.indices.push(a, b, c)\n if (!(pinchTop && j === 0)) this.indices.push(a, c, d)\n }\n }\n }\n\n /**\n * Lay what has been built along another axis: a quarter turn - never a mirror, so faces still\n * face out. From y (turned shapes): x is reached by turning about z, z by turning about x. From z\n * (pushed outlines): x by turning about y, so the outline is seen from +x, and y by turning about\n * x, so it is seen from above.\n * @param {'y' | 'z'} from @param {Axis} to\n */\n turn(from, to) {\n if (from === to) return\n const map = TURNS[from][to]\n for (const list of [this.positions, this.normals]) {\n for (let i = 0; i < list.length; i += 3) {\n const [x, y, z] = map(list[i], list[i + 1], list[i + 2])\n list[i] = x\n list[i + 1] = y\n list[i + 2] = z\n }\n }\n }\n\n /** @param {{ type: string } & Record<string, unknown>} source @returns {Geometry} */\n build(source) {\n const { positions, normals, uvs, indices } = this\n const g = new Geometry({ positions, normals, uvs, indices })\n g.source = source\n return g\n }\n}\n\n/** @type {Record<string, Record<string, (x: number, y: number, z: number) => number[]>>} */\nconst TURNS = {\n y: { x: (x, y, z) => [y, -x, z], z: (x, y, z) => [x, -z, y] },\n z: { x: (x, y, z) => [z, y, -x], y: (x, y, z) => [x, z, -y] },\n}\n\n/**\n * The axis option, or the shape's own when it's missing.\n * @param {string} owner @param {unknown} value @param {Axis} fallback\n * @returns {Axis}\n */\nfunction axisOf(owner, value, fallback) {\n return value === undefined ? fallback : checkOneOf(owner, 'axis', /** @type {Axis} */ (value), ['x', 'y', 'z'])\n}\n\n/**\n * An outline without repeated points. Two in a row - or a last point back at the first, as joined arcs\n * and a rounded rect's straight-less ends give - make a side of no length, which has no direction to\n * face and would crease the smooth sides either side of it (lathe() skips them the same way).\n * @template {ArrayLike<number>} P\n * @param {P[]} points\n * @returns {P[]}\n */\nfunction withoutRepeats(points) {\n const kept = points.filter((p, i) => {\n const q = points[(i + points.length - 1) % points.length]\n return p[0] !== q[0] || p[1] !== q[1]\n })\n return kept.length >= 3 ? kept : points\n}\n","// Flat outlines for extrude() and lathe(): plain lists of [x, y] points, counter-clockwise, so they\n// can be spread into one another to make a shape - a rod's eyes joined by its sides, a cam's base\n// circle and nose. Angles are radians, anticlockwise from +x.\nimport { checkCount, checkLength, checkNumber, describe, fail, resolveOptions } from '../validate.js'\n\n/** @typedef {[number, number]} Point2 */\n\nconst TAU = Math.PI * 2\n\n/** What each outline takes (a number alone sets the first, where that makes sense). */\nexport const OUTLINE_OPTIONS = {\n circle: ['radius', 'segments', 'center'],\n rect: ['size', 'width', 'height', 'radius', 'segments', 'center'],\n polygon: ['radius', 'sides', 'angle', 'center'],\n arc: ['radius', 'from', 'to', 'segments', 'center'],\n gear: ['radius', 'teeth', 'depth', 'center'],\n}\n\nconst HINTS = {\n r: \"use 'radius'\",\n x: \"use center: [x, y]\",\n y: \"use center: [x, y]\",\n centre: \"use 'center'\",\n startAngle: \"use 'from' (radians)\",\n endAngle: \"use 'to' (radians)\",\n cornerRadius: \"use 'radius' for the corners' rounding\",\n n: \"use 'sides' (polygon) or 'segments'\",\n}\n\n/**\n * @typedef {object} CircleOptions\n * @property {number} [radius] default 1\n * @property {number} [segments] points round it, default 32\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * A circle's outline - a hole for an axle, a bolt, a bore.\n * @example extrude({ shape: outline.circle(1), holes: [outline.circle(0.4)], depth: 0.2 }) // a washer\n * @param {number | CircleOptions} [options] a number sets the radius\n * @returns {Point2[]}\n */\nfunction circle(options) {\n const owner = 'outline.circle()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.circle, (n) => ({ radius: n }))\n const radius = checkLength(owner, 'radius', o.radius, 1)\n const segments = checkCount(owner, 'segments', o.segments, 32, 3)\n const [cx, cy] = point(owner, 'center', o.center)\n return Array.from({ length: segments }, (_, i) => {\n const a = i / segments * TAU\n return /** @type {Point2} */ ([cx + Math.cos(a) * radius, cy + Math.sin(a) * radius])\n })\n}\n\n/**\n * @typedef {object} RectOptions\n * @property {number} [size] sets width and height together, default 1\n * @property {number} [width] along x, default size\n * @property {number} [height] along y, default size\n * @property {number} [radius] rounds the corners, default 0 (square)\n * @property {number} [segments] points round each rounded corner, default 8\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * A rectangle's outline, square-cornered or rounded - a plate, a bracket, a slot.\n * @example outline.rect({ width: 4, height: 1.3, radius: 0.2 })\n * @param {number | RectOptions} [options] a number sets width and height\n * @returns {Point2[]}\n */\nfunction rect(options) {\n const owner = 'outline.rect()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.rect, (n) => ({ size: n }))\n const all = checkLength(owner, 'size', o.size, 1)\n const width = checkLength(owner, 'width', o.width, all), height = checkLength(owner, 'height', o.height, all)\n const radius = o.radius === undefined ? 0 : checkNumber(owner, 'radius', o.radius)\n if (radius < 0 || radius > Math.min(width, height) / 2) fail(owner, `'radius' must be from 0 to half the shorter side (${Math.min(width, height) / 2}), got ${radius}`)\n const segments = checkCount(owner, 'segments', o.segments, 8, 1)\n const [cx, cy] = point(owner, 'center', o.center)\n const w = width / 2, h = height / 2\n if (radius === 0) return [[cx - w, cy - h], [cx + w, cy - h], [cx + w, cy + h], [cx - w, cy + h]]\n /** @type {Point2[]} */\n const out = []\n // each corner's arc, anticlockwise from the bottom right\n for (const [x, y, start] of [[w - radius, -h + radius, -Math.PI / 2], [w - radius, h - radius, 0], [-w + radius, h - radius, Math.PI / 2], [-w + radius, -h + radius, Math.PI]]) {\n for (let i = 0; i <= segments; i++) {\n const a = start + i / segments * Math.PI / 2\n out.push([cx + x + Math.cos(a) * radius, cy + y + Math.sin(a) * radius])\n }\n }\n return out\n}\n\n/**\n * @typedef {object} PolygonOptions\n * @property {number} [radius] to the corners, default 1\n * @property {number} [sides] default 6\n * @property {number} [angle] turns it, radians; default 0, a corner on +x\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * A regular polygon's outline - a hex nut, a triangle, an octagon.\n * @example extrude({ shape: outline.polygon({ radius: 0.2, sides: 6 }), holes: [outline.circle(0.1)], depth: 0.1 }) // a nut\n * @param {number | PolygonOptions} [options] a number sets the radius\n * @returns {Point2[]}\n */\nfunction polygon(options) {\n const owner = 'outline.polygon()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.polygon, (n) => ({ radius: n }))\n const radius = checkLength(owner, 'radius', o.radius, 1)\n const sides = checkCount(owner, 'sides', o.sides, 6, 3)\n const angle = o.angle === undefined ? 0 : checkNumber(owner, 'angle', o.angle)\n const [cx, cy] = point(owner, 'center', o.center)\n return Array.from({ length: sides }, (_, i) => {\n const a = angle + i / sides * TAU\n return /** @type {Point2} */ ([cx + Math.cos(a) * radius, cy + Math.sin(a) * radius])\n })\n}\n\n/**\n * @typedef {object} ArcOptions\n * @property {number} [radius] default 1\n * @property {number} [from] start angle, radians anticlockwise from +x; default 0\n * @property {number} [to] end angle; default a whole turn on from `from`. Below `from`, the arc runs clockwise\n * @property {number} [segments] pieces along it, default enough for 32 a turn\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * Points along an arc, both ends included - to join with others into an outline: a connecting\n * rod's two eyes, a crank web's pin end and counterweight.\n * @example extrude({ shape: [...outline.arc({ radius: 0.3, from: 0, to: Math.PI }), ...outline.arc({ radius: 0.6, from: Math.PI, to: 2 * Math.PI, center: [0, -0.5] })] })\n * @param {ArcOptions} [options]\n * @returns {Point2[]}\n */\nfunction arc(options) {\n const owner = 'outline.arc()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.arc, null)\n const radius = checkLength(owner, 'radius', o.radius, 1)\n const from = o.from === undefined ? 0 : checkNumber(owner, 'from', o.from)\n const to = o.to === undefined ? from + TAU : checkNumber(owner, 'to', o.to)\n if (to === from) fail(owner, \"'from' and 'to' are the same angle - there's no arc between them\")\n const segments = checkCount(owner, 'segments', o.segments, Math.max(1, Math.ceil(Math.abs(to - from) / TAU * 32)), 1)\n const [cx, cy] = point(owner, 'center', o.center)\n return Array.from({ length: segments + 1 }, (_, i) => {\n const a = from + (to - from) * i / segments\n return /** @type {Point2} */ ([cx + Math.cos(a) * radius, cy + Math.sin(a) * radius])\n })\n}\n\n/**\n * @typedef {object} GearOptions\n * @property {number} [radius] to the tips of the teeth, default 1\n * @property {number} [teeth] default 24\n * @property {number} [depth] how far the teeth stand out, default a tooth's width\n * @property {ArrayLike<number>} [center] [x, y], default [0, 0]\n */\n\n/**\n * A gear's toothed outline: straight-sided teeth round a root circle - flywheels, sprockets, cogs.\n * @example extrude({ shape: outline.gear({ radius: 1, teeth: 72, depth: 0.05 }), holes: [outline.circle(0.1)], depth: 0.1 })\n * @param {number | GearOptions} [options] a number sets the radius\n * @returns {Point2[]}\n */\nfunction gear(options) {\n const owner = 'outline.gear()'\n const o = resolve(owner, options, OUTLINE_OPTIONS.gear, (n) => ({ radius: n }))\n const radius = checkLength(owner, 'radius', o.radius, 1)\n const teeth = checkCount(owner, 'teeth', o.teeth, 24, 3)\n const depth = checkLength(owner, 'depth', o.depth, Math.min(radius / 2, radius * Math.PI / teeth))\n if (depth >= radius) fail(owner, `'depth' must be less than the radius (${radius}), got ${depth}`)\n const [cx, cy] = point(owner, 'center', o.center)\n const root = radius - depth, step = TAU / teeth\n /** @type {Point2[]} */\n const out = []\n // a tooth: up its leading flank, across the tip, down its trailing flank, then along the root\n for (let i = 0; i < teeth; i++) {\n for (const [f, r] of [[0, root], [0.12, radius], [0.38, radius], [0.5, root]]) {\n const a = (i + f) * step\n out.push([cx + Math.cos(a) * r, cy + Math.sin(a) * r])\n }\n }\n return out\n}\n\n/**\n * Flat outlines for extrude() and lathe(), each a list of [x, y] points. Spread several into one\n * list to build a shape, or pass them as holes.\n */\nexport const outline = { circle, rect, polygon, arc, gear }\n\n// --- checking\n\n/** The shapes' options, with their hints. @param {string} owner @param {unknown} options @param {string[]} keys @param {((n: number) => object) | null} fromNumber */\nconst resolve = (owner, options, keys, fromNumber) => resolveOptions(owner, options, keys, fromNumber, HINTS)\n\n/** @param {string} owner @param {string} name @param {unknown} value @returns {Point2} */\nfunction point(owner, name, value) {\n if (value === undefined) return [0, 0]\n const p = /** @type {any} */ (value)\n if (!p || typeof p !== 'object' || typeof p[0] !== 'number' || typeof p[1] !== 'number' || !Number.isFinite(p[0]) || !Number.isFinite(p[1])) {\n fail(owner, `'${name}' must be [x, y], got ${describe(value)}`)\n }\n return [p[0], p[1]]\n}\n","// Converts phoria v1 model data ({x,y,z} points plus n-gon polygons) into a Geometry - the\n// migration path for hand-made models.\n\nimport { Geometry } from './Geometry.js'\nimport { checkOptions, describe, fail } from '../validate.js'\n\nconst OWNER = 'fromPolygons()'\n\n/**\n * @typedef {object} PolygonData\n * @property {number[]} vertices indices into `points`, 3 or more, counter-clockwise seen from the front\n * @property {number[]} [uvs] a u, v pair per vertex, in the same order\n */\n\n/**\n * @typedef {object} PolygonsOptions\n * @property {Array<{ x: number, y: number, z: number } | number[]>} points\n * @property {PolygonData[]} polygons\n * @property {unknown} [edges] accepted and ignored, so a whole v1 model can be passed; use edges() for wireframes\n * @property {boolean} [smooth] share normals across faces at shared points - curved surfaces look round\n * rather than faceted (default false; only without uvs, where the points stay shared)\n */\n\n/**\n * Make a Geometry from v1-style data. Each polygon is triangulated as a fan from its first vertex\n * (fine for the convex polygons v1 models use) and given flat normals - the faceted v1 look - unless\n * `smooth` is set.\n * Without UVs the points stay shared; if any polygon has UVs every corner gets its own vertex so\n * UVs can differ per face. Other v1 polygon fields (color, texture...) are ignored.\n * @example fromPolygons({ points: [{ x: 0, y: 0, z: 0 }, ...], polygons: [{ vertices: [0, 1, 2, 3] }] })\n * @param {PolygonsOptions} options\n * @returns {Geometry}\n */\nexport function fromPolygons(options) {\n checkOptions(OWNER, options, ['points', 'polygons', 'edges', 'smooth'])\n const { points, polygons } = options ?? /** @type {PolygonsOptions} */ ({})\n if (!Array.isArray(points)) fail(OWNER, `'points' must be an array of { x, y, z } or [x, y, z], got ${describe(points)}`)\n if (!Array.isArray(polygons)) fail(OWNER, `'polygons' must be an array of { vertices: [...] }, got ${describe(polygons)}`)\n\n const xyz = points.map((pt, i) => {\n const c = Array.isArray(pt) ? pt : pt && typeof pt === 'object' ? [pt.x, pt.y, pt.z] : null\n if (!c || c.length !== 3 || !c.every(Number.isFinite)) {\n fail(OWNER, `point ${i} must be { x, y, z } or [x, y, z] numbers, got ${describe(pt)}`)\n }\n return c\n })\n\n polygons.forEach((polygon, p) => {\n const vs = polygon?.vertices\n if (!Array.isArray(vs) || vs.length < 3) fail(OWNER, `polygon ${p} needs 'vertices' with 3 or more point indices, got ${describe(vs)}`)\n for (const v of vs) {\n if (!Number.isInteger(v) || v < 0 || v >= xyz.length) {\n fail(OWNER, `polygon ${p} refers to point ${describe(v)} but there are only ${xyz.length} points`)\n }\n }\n const uvs = polygon.uvs\n if (uvs !== undefined && (!Array.isArray(uvs) || uvs.length !== vs.length * 2 || !uvs.every(Number.isFinite))) {\n fail(OWNER, `polygon ${p} 'uvs' must be ${vs.length * 2} numbers (a u, v pair per vertex), got ${describe(uvs)}`)\n }\n })\n\n // fan triangulation: (0, 1, 2), (0, 2, 3)... keeps each polygon's winding\n /** @type {Array<[number, number]>} [polygon, corner] for each triangle corner */\n const corners = []\n polygons.forEach(({ vertices }, p) => {\n for (let k = 1; k + 1 < vertices.length; k++) corners.push([p, 0], [p, k], [p, k + 1])\n })\n\n let geometry\n const withUvs = polygons.some((p) => p.uvs)\n if (withUvs) {\n const positions = [], uvs = []\n for (const [p, k] of corners) {\n const { vertices, uvs: pu } = polygons[p]\n positions.push(...xyz[vertices[k]])\n uvs.push(pu ? pu[k * 2] : 0, pu ? pu[k * 2 + 1] : 0)\n }\n geometry = new Geometry({ positions, uvs })\n } else {\n geometry = new Geometry({\n positions: xyz.flat(),\n indices: corners.map(([p, k]) => polygons[p].vertices[k]),\n })\n }\n return geometry.computeNormals({ flat: !(options.smooth && !withUvs) })\n}\n","// Curves: a smooth path through points, or an ellipse - to draw as a line, a dashed line or a\n// tube, and to move things along (phoria2/motion). Positions along a curve go by distance, so\n// t = 0.5 is half way along it, however unevenly its points are spaced.\n\nimport { Geometry } from './Geometry.js'\nimport { Vec3 } from '../value/Vec3.js'\nimport { setAxisAngle } from '../math/quat.js'\nimport { checkCount, checkNumber, checkOneOf, checkOptions, describe, fail } from '../validate.js'\n\n/** @import { Vec3Input } from '../types.js' */\n\n/**\n * @typedef {object} CurveOptions\n * @property {boolean} [closed] join the last point back to the first, default false\n * @property {number} [tension] how tightly the curve hugs its points, 0 (round) to 1 (straight lines), default 0\n */\n\n/**\n * @typedef {object} EllipseOptions\n * @property {'xz' | 'xy' | 'yz'} [plane] the plane it lies in, default 'xz' (flat, like an orbit seen from above)\n * @property {number} [radius] sets both radii, default 1\n * @property {number} [radiusX] across x, default radius (planes 'xz' and 'xy')\n * @property {number} [radiusY] across y, default radius (planes 'xy' and 'yz')\n * @property {number} [radiusZ] across z, default radius (planes 'xz' and 'yz')\n * @property {Vec3Input} [center] default [0, 0, 0]\n * @property {number} [tilt] radians about the plane's first axis (x, or y for 'yz'), default 0\n */\n\n/**\n * @typedef {object} LineOptions\n * @property {number} [segments] straight pieces along the whole curve, default by length (about 20 a unit, 400 at most)\n * @property {[number, number]} [dash] [on, off] lengths in the curve's units, for a dashed line\n */\n\n/**\n * @typedef {object} TubeOptions\n * @property {number} [radius] default 0.1\n * @property {number} [segments] rings along the curve, default by length (about 20 a unit, 400 at most)\n * @property {number} [sides] around the tube, default 8\n */\n\n/** What curve(), curve.line(), curve.tube() and ellipse() take, and hints for names people reach for instead. */\nexport const CURVE_OPTIONS = ['closed', 'tension']\nexport const CURVE_HINTS = { loop: \"use 'closed: true'\", smooth: \"the curve is always smooth - 'tension' (0-1) sets how tight\" }\nexport const LINE_OPTIONS = ['segments', 'dash']\nexport const LINE_HINTS = { dashed: \"use 'dash: [on, off]' - lengths in the curve's units\" }\nexport const TUBE_OPTIONS = ['radius', 'segments', 'sides']\nexport const TUBE_HINTS = { tubularSegments: \"use 'segments'\", radialSegments: \"use 'sides'\" }\n// an ellipse takes the two radii of its plane as well: radiusX and radiusZ in 'xz'\nexport const ELLIPSE_OPTIONS = ['plane', 'radius', 'center', 'tilt']\n\nconst SAMPLES = 48 // per span between control points, for measuring length\n\n/** A smooth curve. Make one with curve(points) or ellipse(options). */\nexport class Curve {\n /** @type {Vec3[]} */ #points\n #closed\n #tension\n /** cumulative lengths at even steps of the raw parameter, for going by distance */\n /** @type {Float64Array} */ #lengths\n\n /**\n * @param {Vec3Input[]} points two or more\n * @param {CurveOptions} [options]\n */\n constructor(points, options = {}) {\n if (!Array.isArray(points) || points.length < 2) fail('curve()', `needs an array of two or more points, got ${describe(points)}`)\n checkOptions('curve()', options, CURVE_OPTIONS, CURVE_HINTS)\n this.#points = points.map((p) => Vec3.fromInput(p, 'curve()'))\n this.#closed = !!options.closed\n this.#tension = options.tension === undefined ? 0 : checkNumber('curve()', 'tension', options.tension)\n const n = this.#spans() * SAMPLES\n this.#lengths = new Float64Array(n + 1)\n let prev = this.#raw(0)\n for (let i = 1; i <= n; i++) {\n const p = this.#raw(i / n)\n this.#lengths[i] = this.#lengths[i - 1] + p.distanceTo(prev)\n prev = p\n }\n }\n\n /** Its length, in the units of its points. */\n get length() {\n return this.#lengths[this.#lengths.length - 1]\n }\n\n get closed() {\n return this.#closed\n }\n\n /**\n * The point t of the way along it by distance: 0 is the start, 1 the end.\n * @param {number} t @param {Vec3} [out]\n * @returns {Vec3}\n */\n at(t, out = new Vec3()) {\n return this.#raw(this.#toRaw(t), out)\n }\n\n /**\n * The direction it runs in at t, as a unit vector.\n * @param {number} t @param {Vec3} [out]\n * @returns {Vec3}\n */\n tangentAt(t, out = new Vec3()) {\n const u = this.#toRaw(t), e = 1e-4\n const a = this.#raw(Math.max(0, u - e)), b = this.#raw(Math.min(1, u + e))\n return out.copy(b.sub(a)).normalize()\n }\n\n /**\n * Evenly spaced points along it, for your own geometry.\n * @param {number} count @returns {Vec3[]}\n */\n points(count) {\n const n = checkCount('curve.points()', 'count', count ?? null, 2, 2)\n // a closed curve's last point would repeat its first\n const last = this.#closed ? n : n - 1\n return Array.from({ length: n }, (_, i) => this.at(i / last))\n }\n\n /**\n * Line geometry along it, for a Lines node - solid, or dashed with dash: [on, off].\n * Its pieces run in order from the start, so geometry.drawCount can draw just the first part.\n *\n * scene.add(new Lines({ geometry: path.line({ dash: [0.3, 0.15] }), material: { color: 'orange', width: 2 } }))\n * @param {LineOptions} [options]\n * @returns {Geometry}\n */\n line(options = {}) {\n checkOptions('curve.line()', options, LINE_OPTIONS, LINE_HINTS)\n const segments = this.#segments('curve.line()', options.segments)\n const step = this.length / segments\n /** @type {number[]} */\n const positions = []\n const piece = (from, to) => {\n // a run along the curve, cut into pieces about a step long\n const n = Math.max(1, Math.ceil((to - from) / step - 1e-9))\n let prev = this.at(from / this.length)\n for (let i = 1; i <= n; i++) {\n const p = this.at((from + (to - from) * i / n) / this.length)\n positions.push(prev[0], prev[1], prev[2], p[0], p[1], p[2])\n prev = p\n }\n }\n if (options.dash === undefined) piece(0, this.length)\n else {\n const dash = options.dash\n if (!Array.isArray(dash) || dash.length !== 2 || !dash.every((d) => d > 0)) fail('curve.line()', `'dash' is [on, off], two lengths above 0, got ${describe(dash)}`)\n for (let d = 0; d < this.length; d += dash[0] + dash[1]) piece(d, Math.min(this.length, d + dash[0]))\n }\n return new Geometry({ positions })\n }\n\n /**\n * Tube geometry along it, for a Mesh - a pipe of the curve's shape.\n * @param {TubeOptions} [options]\n * @returns {Geometry}\n */\n tube(options = {}) {\n checkOptions('curve.tube()', options, TUBE_OPTIONS, TUBE_HINTS)\n const radius = options.radius === undefined ? 0.1 : checkNumber('curve.tube()', 'radius', options.radius)\n const sides = checkCount('curve.tube()', 'sides', options.sides, 8, 3)\n const segments = this.#segments('curve.tube()', options.segments)\n const rings = this.#closed ? segments : segments + 1\n /** @type {number[]} */\n const positions = []\n /** @type {number[]} */\n const indices = []\n // each ring's frame is carried along from the last one, so the tube doesn't twist\n let tangent = this.tangentAt(0)\n let normal = new Vec3(...(Math.abs(tangent[1]) < 0.9 ? [0, 1, 0] : [1, 0, 0])).cross(tangent).normalize()\n for (let i = 0; i < rings; i++) {\n const t = i / segments\n const next = this.tangentAt(t)\n // turn the normal by however the tangent turned\n normal = next.clone().cross(normal.clone().cross(next)).normalize()\n tangent = next\n const binormal = tangent.clone().cross(normal)\n const c = this.at(t)\n for (let s = 0; s < sides; s++) {\n const a = s / sides * Math.PI * 2, x = Math.cos(a) * radius, y = Math.sin(a) * radius\n positions.push(c[0] + normal[0] * x + binormal[0] * y, c[1] + normal[1] * x + binormal[1] * y, c[2] + normal[2] * x + binormal[2] * y)\n }\n }\n for (let i = 0; i < segments; i++) {\n const j = (i + 1) % rings\n for (let s = 0; s < sides; s++) {\n const a = i * sides + s, b = j * sides + s, c = j * sides + (s + 1) % sides, d = i * sides + (s + 1) % sides\n indices.push(a, d, c, a, c, b)\n }\n }\n return new Geometry({ positions, indices })\n }\n\n #spans() {\n return this.#closed ? this.#points.length : this.#points.length - 1\n }\n\n /** @param {string} owner @param {number | undefined} segments */\n #segments(owner, segments) {\n if (segments !== undefined) return checkCount(owner, 'segments', segments, 1)\n return Math.min(400, Math.max(8, Math.round(this.length * 20)))\n }\n\n /** The raw curve parameter (even per span) for a distance fraction t. @param {number} t */\n #toRaw(t) {\n const total = this.length, target = Math.min(1, Math.max(0, t)) * total\n const lengths = this.#lengths\n let lo = 0, hi = lengths.length - 1\n while (hi - lo > 1) {\n const mid = (lo + hi) >> 1\n if (lengths[mid] < target) lo = mid\n else hi = mid\n }\n const span = lengths[hi] - lengths[lo]\n return (lo + (span > 0 ? (target - lengths[lo]) / span : 0)) / (lengths.length - 1)\n }\n\n /** A point at raw parameter u (0-1), on a cardinal spline through the points. @param {number} u @param {Vec3} [out] */\n #raw(u, out = new Vec3()) {\n const pts = this.#points, n = pts.length, spans = this.#spans()\n const x = Math.min(1, Math.max(0, u)) * spans\n const i = Math.min(spans - 1, Math.floor(x)), f = x - i\n const get = (k) => (this.#closed ? pts[((k % n) + n) % n] : pts[Math.min(n - 1, Math.max(0, k))])\n const p0 = get(i - 1), p1 = get(i), p2 = get(i + 1), p3 = get(i + 2)\n // centripetal: the tangents weigh each neighbour by the square root of its distance, so\n // unevenly spaced points don't make the curve overshoot into loops or cusps. Evenly spaced,\n // it's the plain Catmull-Rom curve\n const d0 = Math.sqrt(p1.distanceTo(p0)), d1 = Math.sqrt(p2.distanceTo(p1)) || 1e-9, d2 = Math.sqrt(p3.distanceTo(p2))\n const s = 1 - this.#tension\n const f2 = f * f, f3 = f2 * f\n const h1 = 2 * f3 - 3 * f2 + 1, h2 = -2 * f3 + 3 * f2, h3 = f3 - 2 * f2 + f, h4 = f3 - f2\n for (let k = 0; k < 3; k++) {\n const chord = (p2[k] - p1[k]) / d1\n // at an end, where the neighbour is the point itself, the tangent runs along the chord (at half\n // strength, as the plain curve has it)\n const t1 = d0 > 1e-9 ? (p1[k] - p0[k]) / d0 - (p2[k] - p0[k]) / (d0 + d1) + chord : chord / 2\n const t2 = d2 > 1e-9 ? chord - (p3[k] - p1[k]) / (d1 + d2) + (p3[k] - p2[k]) / d2 : chord / 2\n const m1 = s * t1 * d1, m2 = s * t2 * d1\n out[k] = h1 * p1[k] + h2 * p2[k] + h3 * m1 + h4 * m2\n }\n return out\n }\n}\n\n/**\n * A smooth curve through points - for paths, routes and trajectories.\n *\n * const route = curve([[0, 0, 0], [2, 3, 0], [6, 2, 1]])\n * route.at(0.5) // half way along, by distance\n * @param {Vec3Input[]} points\n * @param {CurveOptions} [options]\n * @returns {Curve}\n */\nexport function curve(points, options) {\n return new Curve(points, options)\n}\n\n/**\n * A closed ellipse - for orbits. It lies flat in x-z unless plane says otherwise, and starts on its\n * first axis, running toward its second: from +x toward +z in 'xz'.\n *\n * const orbit = ellipse({ radiusX: 4, radiusZ: 3, center: [8, 0, 0] })\n * const face = ellipse({ plane: 'xy', radiusX: 3, radiusY: 2 }) // facing the camera\n * @param {EllipseOptions} [options]\n * @returns {Curve}\n */\nexport function ellipse(options = {}) {\n const plane = options.plane === undefined ? 'xz' : checkOneOf('ellipse()', 'plane', options.plane, ['xz', 'xy', 'yz'])\n const [u, v] = [...plane].map((a) => 'xyz'.indexOf(a))\n const name = (a) => `radius${'XYZ'[a]}`\n const off = name(3 - u - v)\n checkOptions('ellipse()', options, [...ELLIPSE_OPTIONS, name(u), name(v)], {\n [off]: `an ellipse in '${plane}' has '${name(u)}' and '${name(v)}' - set plane for another`,\n })\n const r = options.radius === undefined ? 1 : checkNumber('ellipse()', 'radius', options.radius)\n const radius = (a) => (options[name(a)] === undefined ? r : checkNumber('ellipse()', name(a), options[name(a)]))\n const ru = radius(u), rv = radius(v)\n const c = Vec3.fromInput(options.center ?? [0, 0, 0], 'ellipse()')\n const tilt = options.tilt === undefined ? 0 : checkNumber('ellipse()', 'tilt', options.tilt)\n const axis = [0, 0, 0]\n axis[u] = 1\n const turn = setAxisAngle(new Float32Array(4), axis, tilt)\n // enough points that the spline through them is a true ellipse to well under a pixel\n const n = 64\n const points = Array.from({ length: n }, (_, i) => {\n const a = i / n * Math.PI * 2, p = new Vec3()\n p[u] = Math.cos(a) * ru\n p[v] = Math.sin(a) * rv\n return p.applyQuaternion(turn).add(c)\n })\n return new Curve(points, { closed: true })\n}\n","// Node types added from outside the core (a chart from phoria2/charts), so create() can build their\n// descriptions. Kept apart from describe.js so registering a type doesn't pull in every node class.\n\n/** @type {Map<string, new (options: any) => any>} */\nconst types = new Map()\n\n/**\n * Let create() build descriptions of this node class, by its static `type`. Sub-path modules\n * (phoria2/charts) register theirs when imported. A class with options of its own adds them to its\n * parent's, so the node options still work:\n *\n * class Beacon extends Group {\n * static type = 'beacon'\n * static get OPTIONS() { return [...super.OPTIONS, 'blink'] }\n * }\n * registerType(Beacon)\n * @param {(new (options: any) => any) & { type: string }} Class\n */\nexport function registerType(Class) {\n types.set(Class.type, Class)\n}\n\n/** @internal */\nexport function registeredTypes() {\n return types\n}\n","// Plain-data descriptions: create() builds any node from { type: 'mesh', ... }, the inverse of\n// node.toJSON(). Every constructor's options are its description, plus the type. This is the one\n// place descriptions are accepted, so apps that never use them don't carry this module (or every\n// geometry generator).\nimport { describe, didYouMean, fail, checkOneOf } from './validate.js'\nimport { Geometry } from './geometry/Geometry.js'\nimport * as generators from './geometry/generators.js'\nimport { Node, Group } from './scene/Node.js'\nimport { Scene } from './scene/Scene.js'\nimport { InstancedMesh, Label, Lines, Mesh, Points } from './scene/drawables.js'\nimport { OrthographicCamera, PerspectiveCamera } from './scene/cameras.js'\nimport { AmbientLight, DirectionalLight, HemisphereLight, PointLight, SpotLight } from './scene/lights.js'\nimport { registeredTypes } from './registry.js'\n\n/** Generator types usable in geometry descriptions: { type: 'box', size: 2 }. */\nexport const GEOMETRY_TYPES = ['box', 'sphere', 'plane', 'cylinder', 'torus', 'icosphere', 'lathe', 'extrude', 'axes', 'grid']\n\n// Built on first use, not at module load, so these modules can import each other in any order.\n/** @type {Map<string, new (options: any) => Node> | null} */\nlet types = null\nconst typeMap = () => {\n types ??= new Map([\n Node, Group, Scene, Mesh, InstancedMesh, Points, Lines, Label, PerspectiveCamera, OrthographicCamera,\n AmbientLight, HemisphereLight, DirectionalLight, PointLight, SpotLight,\n ].map((Class) => [Class.type, Class]))\n // plus types registered by sub-paths, such as 'chart' from phoria2/charts\n for (const [type, Class] of registeredTypes()) types.set(type, Class)\n return types\n}\n\n// The names people coming from three.js will type\nconst THREE_TYPES = {\n Mesh: 'mesh', Group: 'group', Object3D: 'node', Points: 'points', LineSegments: 'lines', Line: 'lines',\n InstancedMesh: 'instanced-mesh', PerspectiveCamera: 'perspective-camera', OrthographicCamera: 'orthographic-camera',\n AmbientLight: 'ambient-light', HemisphereLight: 'hemisphere-light', DirectionalLight: 'directional-light',\n PointLight: 'point-light', SpotLight: 'spot-light', Scene: 'scene', light: 'directional-light', camera: 'perspective-camera',\n}\n// sub-path types that aren't registered until their module is imported\nconst SUBPATH_TYPES = { chart: \"import { chart } from 'phoria2/charts' first, which registers 'chart'\", emitter: \"'emitter' descriptions aren't supported yet - use new Emitter() from 'phoria2/particles'\" }\n\n// geometry names people reach for, and three.js geometry classes\nconst GEOMETRY_ALIASES = {\n cube: 'box', ball: 'sphere', globe: 'sphere', quad: 'plane', tube: 'cylinder', ring: 'torus', donut: 'torus',\n BoxGeometry: 'box', SphereGeometry: 'sphere', PlaneGeometry: 'plane', CylinderGeometry: 'cylinder',\n TorusGeometry: 'torus', IcosahedronGeometry: 'icosphere', GridHelper: 'grid', AxesHelper: 'axes',\n LatheGeometry: 'lathe', ExtrudeGeometry: 'extrude', ShapeGeometry: 'extrude',\n}\n\n/** @param {string} type @returns {string | null} a hint when a material or geometry is described as a node */\nfunction notANode(type) {\n if (/Material$/.test(type)) return `materials aren't nodes - give a mesh material: { color, roughness, metalness, ... }`\n const geometry = GEOMETRY_ALIASES[type]\n if (geometry) return `geometry isn't a node - give a mesh geometry: { type: '${geometry}', ... }`\n return null\n}\n\n/**\n * Build a node (and its children) from a description: its constructor options plus a `type`, as\n * produced by node.toJSON(). Children and geometry may be descriptions too.\n *\n * scene.add(create({ type: 'mesh', geometry: { type: 'box', size: 2 }, material: { color: 'orange' } }))\n *\n * Textures named by url start loading straight away; `await scene.ready` waits for them.\n * @template {Node} [T=Node]\n * @param {{ type: string } & Record<string, any>} description\n * @returns {T}\n */\nexport function create(description) {\n if (description instanceof Node) return /** @type {T} */ (description)\n if (!description || typeof description !== 'object' || Array.isArray(description)) {\n fail('create()', `expected a description such as { type: 'mesh', ... }, got ${describe(description)}`)\n }\n const { type, ...options } = description\n if (typeof type !== 'string') {\n fail('create()', `a description needs a 'type': one of ${[...typeMap().keys()].join(', ')}`)\n }\n const Class = typeMap().get(type)\n if (!Class) {\n const three = THREE_TYPES[type], misplaced = notANode(type) ?? SUBPATH_TYPES[type]\n fail('create()', `unknown type '${type}' - ${three ? `use '${three}'` : misplaced ?? `expected one of ${[...typeMap().keys()].join(', ')}${didYouMean(type, typeMap().keys())}`}`)\n }\n if (Array.isArray(options.children)) options.children = options.children.map((c) => create(c))\n if (options.geometry && !(options.geometry instanceof Geometry) && typeof options.geometry === 'object' && 'type' in options.geometry) {\n options.geometry = createGeometry(options.geometry, `create({ type: '${type}' })`)\n }\n return /** @type {T} */ (new Class(options))\n}\n\n/**\n * A Geometry from a generator description such as { type: 'sphere', radius: 2 }.\n * @param {{ type: string } & Record<string, unknown>} description\n * @param {string} [owner]\n * @returns {Geometry}\n */\nexport function createGeometry(description, owner = 'createGeometry()') {\n const { type, ...options } = description\n const alias = GEOMETRY_ALIASES[type]\n if (alias) fail(owner, `geometry type '${type}' - use '${alias}'`)\n checkOneOf(owner, 'geometry.type', type, GEOMETRY_TYPES)\n const make = /** @type {(o: any) => Geometry} */ (generators[type])\n return make(Object.keys(options).length ? options : undefined)\n}\n"],"mappings":"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"}
|