@saboit-dev/thomas 1.1.0-alpha.1 → 1.1.0-alpha.2
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/index.cjs.js +1 -1
- package/package.json +1 -1
- package/text_engine_2d/MSDFTextGeometry/TextLayout.cjs.js +1 -1
- package/text_engine_2d/MSDFTextGeometry/TextLayout.js +50 -47
- package/text_engine_2d/MSDFTextGeometry/index.cjs.js +1 -1
- package/text_engine_2d/MSDFTextGeometry/index.d.ts +10 -1
- package/text_engine_2d/MSDFTextGeometry/index.js +138 -44
package/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("three"),t=require("quad-indices"),n=require("word-wrapper"),r=require("react"),i=require("@babel/runtime/helpers/extends"),o=require("@react-three/drei"),s=require("@react-three/fiber"),a=require("three/examples/jsm/loaders/FontLoader");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var c=l(t),h=l(n),f=u(r),d=l(i);const p=["x","e","a","o","n","s","r","c","u","m","v","w","z"],g=["m","w"],x=["H","I","N","E","F","K","L","T","U","V","W","X","Y","Z"],m="\t".charCodeAt(0),y=" ".charCodeAt(0),v=1,b=2;class S{_options={};_width=0;_height=0;_descender=0;_ascender=0;_xHeight=0;_baseline=0;_capHeight=0;_lineHeight=0;_linesTotal=0;_lettersTotal=0;_wordsTotal=0;_fallbackSpaceGlyph=null;_fallbackTabGlyph=null;constructor(e,t={}){this.glyphs=[],this._text=e,this._measure=this.computeMetrics.bind(this),this.update(t)}get width(){return this._width}get height(){return this._height}get descender(){return this._descender}get ascender(){return this._ascender}get xHeight(){return this._xHeight}get baseline(){return this._baseline}get capHeight(){return this._capHeight}get lineHeight(){return this._lineHeight}get linesTotal(){return this._linesTotal}get lettersTotal(){return this._lettersTotal}get wordsTotal(){return this._wordsTotal}update(e){if(e=Object.assign({measure:this._measure},e),this._options=e,this._options.tabSize=_(this._options.tabSize,4),!e.font)throw new Error("must provide a valid bitmap font");const t=this.glyphs,n=this._text||"",r=e.font;this._setupSpaceGlyphs(r);const i=h.default.lines(n,e),o=e.width||0,s=n.split(" ").filter((e=>"\n"!==e)).length,a=n.split("").filter((e=>"\n"!==e&&" "!==e)).length;t.length=0;const l=i.reduce((function(e,t){return Math.max(e,t.width,o)}),0);let u=0,c=0;const f=_(e.lineHeight,r.common.lineHeight),d=r.common.base,g=f-d,m=e.letterSpacing||0,S=f*i.length-g,w=function(e){if("center"===e)return v;if("right"===e)return b;return 0}(this._options.alignX);c-=S,this._width=l,this._height=S,this._descender=f-d,this._baseline=d,this._xHeight=function(e){for(const t of p){const n=M(e.chars,t.charCodeAt(0));if(n>=0)return e.chars[n].height}return 0}(r),this._capHeight=function(e){for(const t of x){const n=M(e.chars,t.charCodeAt(0));if(n>=0)return e.chars[n].height}return 0}(r),this._lineHeight=f,this._ascender=f-g-this._xHeight;let B=0,C=0;i.forEach(((e,o)=>{const h=e.start,d=e.end,p=e.width,g=n.slice(h,d).split(" ").filter((e=>""!==e)).length,x=n.slice(h,d).split(" ").join("").length;let S,M=0,_=0;for(let e=h;e<d;e++){const h=n.charCodeAt(e),f=this.getGlyph(r,h);if(f){S&&(u+=A(r,S.id,f.id));let n=u;w===v?n+=(l-p)/2:w===b&&(n+=l-p),t.push({position:[n,c],data:f,index:e,linesTotal:i.length,lineIndex:o,lineLettersTotal:x,lineLetterIndex:M,lineWordsTotal:g,lineWordIndex:_,wordsTotal:s,wordIndex:B,lettersTotal:a,letterIndex:C}),f.id===y&&S.id!==y&&(_++,B++),f.id!==y&&(M++,C++),u+=f.xadvance+m,S=f}}c+=f,u=0})),this._lettersTotal=a,this._wordsTotal=s,this._linesTotal=i.length}getGlyph(e,t){const n=w(e,t);return n||(t===m?this._fallbackTabGlyph:t===y?this._fallbackSpaceGlyph:null)}computeMetrics(e,t,n,r){const i=this._options.letterSpacing||0,o=this._options.font;let s,a,l=0,u=0,c=0;if(!o.chars||0===o.chars.length)return{start:t,end:t,width:0};n=Math.min(e.length,n);for(let h=t;h<n;h++){const t=e.charCodeAt(h);if(s=this.getGlyph(o,t),s){s.char=e[h];l+=a?A(o,a.id,s.id):0;const t=l+s.xadvance+i,n=l+s.width;if(n>=r||t>=r)break;l=t,u=n,a=s}c++}return a&&(u+=a.xoffset),{start:t,end:t+c,width:u}}_setupSpaceGlyphs(e){var t;if(this._fallbackSpaceGlyph=null,this._fallbackTabGlyph=null,!e.chars||0===e.chars.length)return;const n=w(e,y)||function(e){for(const t of g){const n=M(e.chars,t.charCodeAt(0));if(n>=0)return e.chars[n]}return 0}(e)||e.chars[0],r=(null!==(t=this._options.tabSize)&&void 0!==t?t:1)*n.xadvance;this._fallbackSpaceGlyph=n;const i=Object.assign({},n);this._fallbackTabGlyph=Object.assign(i,{x:0,y:0,xadvance:r,id:m,xoffset:0,yoffset:0,width:0,height:0})}}function w(e,t){if(!e.chars||0===e.chars.length)return null;const n=M(e.chars,t);if(n>=0){return e.chars[n]}return null}function A(e,t,n){if(!e.kernings||0===e.kernings.length)return 0;const r=e.kernings;for(const e of r)if(e.first===t&&e.second===n)return e.amount;return 0}function M(e,t,n){for(let r=n=n||0;r<e.length;r++)if(e[r].id===t)return r;return-1}function _(e,t){return"number"==typeof e?e:"number"==typeof t?t:0}const B=3,C={min:[0,0,0],max:[0,0,0]};function I(e){const t=e.length/B;C.min[0]=e[0],C.min[1]=e[1],C.max[0]=e[0],C.max[1]=e[1];for(let n=0;n<t;n++){const t=e[n*B+0],r=e[n*B+1],i=e[n*B+2];C.min[0]=Math.min(t,C.min[0]),C.min[1]=Math.min(r,C.min[1]),C.min[2]=Math.min(i,C.min[2]),C.max[0]=Math.max(t,C.max[0]),C.max[1]=Math.max(r,C.max[1]),C.max[2]=Math.max(i,C.max[2])}}function T(e,t){return I(e),t.min.set(C.min[0],C.min[1],C.min[2]),t.max.set(C.max[0],C.max[1],C.max[2]),t}const G=new e.Vector3,P=new e.Vector3,F=new e.Vector3,O=new e.Vector3;class E extends e.BufferGeometry{originalPositionsArray=new Float32Array;positionsArray=new Float32Array;positionsAttribute=null;instancesOffsetsCache=[];instancesLengthsCache=[];constructor(e){super(),this._layouts=[],this.update(e)}setTransform(e,t=0){const n=this.instancesOffsetsCache[t],r=this.instancesLengthsCache[t];for(let t=0;t<r;t++){const r=12*n+12*t,i=this.originalPositionsArray[r],o=this.originalPositionsArray[r+1],s=this.originalPositionsArray[r+2],a=this.originalPositionsArray[r+3],l=this.originalPositionsArray[r+4],u=this.originalPositionsArray[r+5],c=this.originalPositionsArray[r+6],h=this.originalPositionsArray[r+7],f=this.originalPositionsArray[r+8],d=this.originalPositionsArray[r+9],p=this.originalPositionsArray[r+10],g=this.originalPositionsArray[r+11];G.set(i,o,s).applyMatrix4(e),P.set(a,l,u).applyMatrix4(e),F.set(c,h,f).applyMatrix4(e),O.set(d,p,g).applyMatrix4(e),this.positionsArray[r]=G.x,this.positionsArray[r+1]=G.y,this.positionsArray[r+2]=G.z,this.positionsArray[r+3]=P.x,this.positionsArray[r+4]=P.y,this.positionsArray[r+5]=P.z,this.positionsArray[r+6]=F.x,this.positionsArray[r+7]=F.y,this.positionsArray[r+8]=F.z,this.positionsArray[r+9]=O.x,this.positionsArray[r+10]=O.y,this.positionsArray[r+11]=O.z}this.positionsAttribute&&(this.positionsAttribute.needsUpdate=!0)}update(t){const{texts:n,...r}=t;this._layouts=n.map((e=>function(e,t){return new S(e,t)}(e.text,{...r,...e})));const i=!1!==t.flipY,o=t.font,s=o.common.scaleW,a=o.common.scaleH,l=this._layouts.map((e=>e.glyphs.filter((e=>{const t=e.data;return t.width*t.height>0}))));this.instancesOffsetsCache=[],this.instancesLengthsCache=[];let u=0;l.forEach(((e,t)=>{this.instancesLengthsCache[t]=e.length,this.instancesOffsetsCache[t]=u,u+=e.length}));const h=u,f=c.default([],{clockwise:!0,type:"uint16",count:h});this.setIndex(f);const d=l.map((e=>function(e,t,n,r){const i=new Float32Array(4*e.length*2),o=new Float32Array(4*e.length*3),s=new Float32Array(4*e.length*2);let a=0,l=0,u=0;return e.forEach((function(e){const c=e.data,h=c.x+c.width,f=c.y+c.height,d=c.x/t;let p=c.y/n;const g=h/t;let x=f/n;r&&(p=(n-c.y)/n,x=(n-f)/n),i[a++]=d,i[a++]=p,i[a++]=d,i[a++]=x,i[a++]=g,i[a++]=x,i[a++]=g,i[a++]=p;const m=e.position[0]+c.xoffset,y=e.position[1]+c.yoffset,v=c.width,b=c.height;o[l++]=m,o[l++]=y,o[l++]=0,o[l++]=m,o[l++]=y+b,o[l++]=0,o[l++]=m+v,o[l++]=y+b,o[l++]=0,o[l++]=m+v,o[l++]=y,o[l++]=0,s[u++]=m+v/2,s[u++]=y+b/2,s[u++]=m+v/2,s[u++]=y+b/2,s[u++]=m+v/2,s[u++]=y+b/2,s[u++]=m+v/2,s[u++]=y+b/2})),{uvs:i,positions:o,centers:s}}(e,s,a,i))),p=d.reduce(((e,t)=>e+t.positions.length),0),g=d.reduce(((e,t)=>e+t.centers.length),0),x=d.reduce(((e,t)=>e+t.uvs.length),0),m=new Float32Array(p),y=new Float32Array(g),v=new Float32Array(x);let b=0,w=0,A=0;d.forEach((e=>{m.set(e.positions,b),b+=e.positions.length,y.set(e.centers,w),w+=e.centers.length,v.set(e.uvs,A),A+=e.uvs.length})),this.positionsArray=m,this.originalPositionsArray=new Float32Array(p),this.originalPositionsArray.set(m),this.positionsAttribute=new e.BufferAttribute(m,3),this.setAttribute("position",this.positionsAttribute),this.setAttribute("center",new e.BufferAttribute(y,2)),this.setAttribute("uv",new e.BufferAttribute(v,2))}computeBoundingSphere(){null===this.boundingSphere&&(this.boundingSphere=new e.Sphere);const t=this.attributes.position.array,n=this.attributes.position.itemSize;if(!t||!n||t.length<2)return this.boundingSphere.radius=0,void this.boundingSphere.center.set(0,0,0);!function(e,t){I(e);const n=C.min[0],r=C.min[1],i=C.min[2],o=C.max[0]-n,s=C.max[1]-r,a=C.max[2]-i,l=Math.sqrt(o*o+s*s+a*a);t.center.set(n+o/2,r+s/2,i+a/2),t.radius=l/2}(t,this.boundingSphere),isNaN(this.boundingSphere.radius)&&console.error('BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.')}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new e.Box3);const t=this.boundingBox,n=this.attributes.position.array,r=this.attributes.position.itemSize;if(!n||!r||n.length<2)return void t.makeEmpty();return T(n,t)}}class k extends e.ShaderMaterial{constructor(t={}){super(t={...{side:e.FrontSide,transparent:!0,extensions:{derivatives:!0},uniforms:{uOpacity:{value:1},uOffset:{value:0},uColor:{value:new e.Color("#ffffff")},uMap:{value:null}},vertexShader:"#define GLSLIFY 1\nvarying vec2 vUv;void main(){vec4 mvPosition=vec4(position,1.0);mvPosition=modelViewMatrix*mvPosition;gl_Position=projectionMatrix*mvPosition;vUv=uv;}",fragmentShader:"#define GLSLIFY 1\nvarying vec2 vUv;uniform float uOpacity;uniform float uOffset;uniform vec3 uColor;uniform sampler2D uMap;float median(float r,float g,float b){return max(min(r,g),min(max(r,g),b));}void main(){vec3 s=texture2D(uMap,vUv).rgb;float sigDist=median(s.r,s.g,s.b)-0.5+uOffset;float alpha=clamp(sigDist/fwidth(sigDist)+0.5,0.0,1.0);if(alpha<0.01)discard;gl_FragColor=vec4(uColor,uOpacity*alpha);}"},...t})}}const H=r.createContext(null),V=e=>{var t,n;return[e.bold,null==(t=e.color)?void 0:t.getHexString(),e.opacity,e.outlineWidth,e.outlineOpacity,null==(n=e.outlineColor)?void 0:n.getHexString()].join("_")},L=r.forwardRef((function({instanceKey:e,bold:t,color:n,opacity:i,outlineWidth:o,outlineOpacity:s,outlineColor:a,text:l,alignX:u,alignY:c,letterSpacing:h,yShift:d,width:p,lineHeight:g,onBeforeUpdate:x},m){const y=r.useContext(H);if(!y)throw new Error("No SDFTextProvider");const v=r.useRef(null),b=r.useRef(null);return r.useImperativeHandle(m,(()=>({setTransform(e){b.current&&(b.current.transform=e)}})),[]),r.useLayoutEffect((()=>{var r;const f={bold:t,color:n,opacity:i,outlineWidth:o,outlineOpacity:s,outlineColor:a},m={text:l,alignX:u,alignY:c,letterSpacing:h,yShift:d,width:p,lineHeight:g,onBeforeUpdate:x},S=V(f);return b.current=y.insertInstance(S,f,e,m,null!==(r=v.current)&&void 0!==r?r:void 0),()=>y.removeInstance(S,e)}),[y,e,l,u,c,h,d,p,g,t,n,i,o,s,a,x]),f.createElement("group",{ref:v})}));function D(){s.extend({MSDFTextMaterial:k,MSDFTextGeometry:E})}const j=99999,U=99998,W=new e.Matrix4,z=new e.Matrix4,N=new e.Color("#ffffff"),R=new e.Color("#000000"),q=.01;function Y({instances:e,textStyle:t,atlas:n,font:i,atlasBold:o,fontBold:a,...l}){var u;const c=o&&a&&t.bold,h=c?a.data:i.data,p=r.useState((()=>new E({font:h,texts:[]})))[0];r.useLayoutEffect((()=>()=>p.dispose()),[p]),r.useLayoutEffect((()=>{const t=e.map((e=>e.config));p.update({font:h,texts:t})}),[p,e,h]),s.useFrame((()=>{e.forEach(((t,n)=>{null==t.config.onBeforeUpdate||t.config.onBeforeUpdate(),z.identity();const r=e[n].object;r&&(r.updateMatrixWorld(),z.multiply(r.matrixWorld)),z.multiply(t.transform),W.makeScale(q,q,q),z.multiply(W);const i=p._layouts[n];if(i){var o,s,a,l;const e=null!==(o=i.width)&&void 0!==o?o:0,t=null!==(s=i.height)&&void 0!==s?s:0,n=null!==(a=i.lineHeight)&&void 0!==a?a:0,r=null!==(l=i._options.yShift)&&void 0!==l?l:0,u=n/4-t,c=n/2;let h=0;"center"===i._options.alignX&&(h=-e/2),"right"===i._options.alignX&&(h=-e);let f=u+r;"middle"===i._options.alignY&&(f=(u+c)/2-i.ascender+r),"bottom"===i._options.alignY&&(f=c+r),W.makeTranslation(h,f,0),z.multiply(W)}W.makeRotationX(Math.PI),z.multiply(W),p.setTransform(z,n)}))}));const g=r.useMemo((()=>{var e,r;return{uMap:{value:c?o:n},uColor:{value:null!==(e=t.color)&&void 0!==e?e:N},uOpacity:{value:null!==(r=t.opacity)&&void 0!==r?r:1},uOffset:{value:0}}}),[c,t.opacity,t.color,n,o]),x=r.useMemo((()=>{var e,r;return{uMap:{value:c?o:n},uColor:{value:null!==(e=t.outlineColor)&&void 0!==e?e:R},uOpacity:{value:null!==(r=t.outlineOpacity)&&void 0!==r?r:.4},uOffset:{value:t.outlineWidth}}}),[c,t.outlineOpacity,t.outlineColor,t.outlineWidth,n,o]);return f.createElement(f.Fragment,null,f.createElement("mesh",d.default({geometry:p,frustumCulled:!1,renderOrder:j},l),f.createElement("mSDFTextMaterial",{uniforms:g})),(null!==(u=t.outlineWidth)&&void 0!==u?u:0)>0&&f.createElement("mesh",d.default({geometry:p,frustumCulled:!1,renderOrder:U},l),f.createElement("mSDFTextMaterial",{uniforms:x,depthWrite:!1})))}const X=new e.Matrix4,K=new e.Matrix4;function Z(){s.extend({InstancedTextPlaceholder:ne})}class J{boundingBox=null;boundingSphere=null;computeBoundingBox(){this.boundingBox||(this.boundingBox=new e.Box3)}computeBoundingSphere(){this.boundingSphere||(this.boundingSphere=new e.Sphere)}}const Q=new e.Matrix4,$=new e.Ray,ee=new e.Sphere,te=new e.Vector3;class ne extends e.Group{textAPI=void 0;geometry=new J;raycast(e,t){const n=this.geometry,r=this.matrixWorld;null===n.boundingSphere&&n.computeBoundingSphere(),ee.copy(n.boundingSphere),ee.applyMatrix4(r),!1!==e.ray.intersectsSphere(ee)&&(Q.copy(r).invert(),$.copy(e.ray).applyMatrix4(Q),null!==n.boundingBox&&null===$.intersectBox(n.boundingBox,te)||t.push({distance:te.distanceTo(e.ray.origin),point:te.clone(),object:this}))}}const re=()=>new e.MeshPhongMaterial;function ie(t,n,i,o=re){return r.useMemo((()=>{const r=o();return r.onBeforeCompile=r=>{r.uniforms={...r.uniforms,offsets:{value:t},normals:{value:n},shift:{value:new e.Vector3(i.xShift,i.yShift,i.zShift)},scale:{value:new e.Vector3(i.xScale,i.yScale,i.zScale)}},r.vertexShader=r.vertexShader.replace(/#include <morphtarget_pars_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <morphtarget_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <morphcolor_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <morphnormal_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <skinning_pars_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <skinbase_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <skinning_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <skinnormal_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <displacementmap_pars_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <displacementmap_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/>[\n]*void/,">\n uniform sampler2D offsets;\n uniform sampler2D normals;\n uniform vec3 shift;\n uniform vec3 scale;\n in float instanceGIndex;\n\n void"),r.vertexShader=r.vertexShader.replace(/void main\(\) {/,"void main() { vec3 offset = texelFetch(offsets, ivec2(gl_VertexID, instanceGIndex), 0).rgb * scale + shift;"),r.vertexShader=r.vertexShader.replace(/#include <beginnormal_vertex>/,"vec3 objectNormal = (texelFetch(normals, ivec2(gl_VertexID, instanceGIndex), 0).rgb) - 0.5;"),r.vertexShader=r.vertexShader.replace(/#include <begin_vertex>/,"vec3 transformed = offset;")},r}),[t,n,i,o])}function oe(t){const n=o.useTexture(t);return n.flipY=!1,n.magFilter=e.NearestFilter,n.minFilter=e.NearestFilter,n}const se=r.createContext(null);const ae=r.forwardRef((function({font:t},n){const i=ie(oe(t.offsetsPath),oe(t.normalsPath),t.fontMetadata),[{instanceAllocated:o,geometry:a},l]=r.useState({instanceAllocated:0,geometry:null}),u=r.useRef(null),c=r.useCallback((n=>(u.current=function(t,n,r){var i,o,s,a;null==t||t.geometry.dispose();const l=new e.InstancedBufferGeometry;l.instanceCount=n;const u=new Float32Array(3*r),c=new e.Float32BufferAttribute(u,3,!1);l.setAttribute("position",c);const h=new Float32Array(16*l.instanceCount),f=new e.InstancedBufferAttribute(h,16,!1,1);l.setAttribute("instanceMatrix",f);const d=new Float32Array(l.instanceCount);t&&d.set(t.currentGlyphs);const p=new e.InstancedBufferAttribute(d,1,!1,1);l.setAttribute("instanceGIndex",p);const g=new Float32Array(4*l.instanceCount);t&&g.set(t.currentColors);const x=new e.InstancedBufferAttribute(g,4,!0,1);return l.setAttribute("instanceColor",x),{instanceAllocated:n,geometry:l,currentInstances:null!==(i=null==t?void 0:t.currentInstances)&&void 0!==i?i:[],currentGlyphs:null!==(o=null==t?void 0:t.currentGlyphs)&&void 0!==o?o:[],currentShifts:null!==(s=null==t?void 0:t.currentShifts)&&void 0!==s?s:[],currentColors:null!==(a=null==t?void 0:t.currentColors)&&void 0!==a?a:[],instanceMatrixBuffer:h,instanceMatrixBufferAttribute:f,instanceGIndexBuffer:d,instanceGIndexBufferAttribute:p,instanceColorBuffer:g,instanceColorBufferAttribute:x}}(u.current,n,t.fontMetadata.maxVertices),l({instanceAllocated:n,geometry:u.current.geometry}),u.current)),[t.fontMetadata.maxVertices]);return r.useImperativeHandle(n,(()=>({font:t,addInstances:(e,t,n,r,i)=>{var o;const s=null!==(o=u.current)&&void 0!==o?o:c(2*e.length),a=function(e,t,n,r,i,o,s){const a=e.currentGlyphs.length,l=n.length,u=Array.from(n).map((e=>t[e])),c=Array.from(n).flatMap((()=>[i.r,i.g,i.b,1]));e.currentGlyphs.push(...u),e.currentShifts.push(...o),e.currentColors.push(...c);const h={start:a,length:l,text:n,parentGroup:s,font:r};return e.currentInstances.push(h),h}(s,t.fontMetadata.charToIndex,e,t,n,r,i);return s.currentGlyphs.length>s.instanceAllocated?c(2*s.currentGlyphs.length):function(e){e.instanceGIndexBuffer.set(e.currentGlyphs),e.instanceGIndexBufferAttribute.needsUpdate=!0,e.instanceColorBuffer.set(e.currentColors),e.instanceColorBufferAttribute.needsUpdate=!0}(s),a},removeInstances:e=>{const t=u.current;t&&function(e,t){const n=e.currentInstances.indexOf(t);if(-1!==n){for(let r=0;r<e.currentInstances.length;r++)r>n&&(e.currentInstances[r].start-=t.length);e.currentInstances.splice(n,1),e.currentGlyphs.splice(t.start,t.length),e.currentShifts.splice(2*t.start,2*t.length),e.currentColors.splice(4*t.start,4*t.length),e.instanceGIndexBuffer.fill(0),e.instanceGIndexBuffer.set(e.currentGlyphs),e.instanceGIndexBufferAttribute.needsUpdate=!0,e.instanceColorBuffer.fill(0),e.instanceColorBuffer.set(e.currentColors),e.instanceColorBufferAttribute.needsUpdate=!0,e.instanceMatrixBuffer.fill(0),e.instanceMatrixBufferAttribute.needsUpdate=!0}}(t,e)},setOpacity:(e,t)=>{const n=u.current;if(n&&n.instanceColorBuffer&&n.instanceColorBufferAttribute){for(let r=0;r<e.length;r++)n.currentColors[4*(e.start+r)+3]=t,n.instanceColorBuffer[4*(e.start+r)+3]=t;n.instanceColorBufferAttribute.needsUpdate=!0}},getBuffers:()=>u.current})),[t,c]),s.useFrame((()=>{const e=u.current;e&&function(e){e.currentInstances.forEach((t=>{for(let n=0;n<t.length;n++){const r=e.currentShifts[2*(t.start+n)],i=e.currentShifts[2*(t.start+n)+1];K.copy(t.parentGroup.matrixWorld),X.identity().setPosition(r,i,0),K.multiply(X),K.toArray(e.instanceMatrixBuffer,16*(t.start+n))}})),e.instanceMatrixBufferAttribute.needsUpdate=!0}(e)})),a?f.createElement("instancedMesh",{frustumCulled:!1,args:[a,i,o]}):null}));let le=function(e){return e.left="left",e.right="right",e.center="center",e}({});const ue=new e.Color("white");exports.InstancedText=function({text:t,thickness:n,fontSize:i,textAlign:o,scale:s,color:a,opacity:l,font:u,...c}){var h,p,g;const x=u.fontMetadata.charToIndex["?"],m=function(){const e=r.useContext(se);if(!e)throw new Error("No instanced text context");return e}(),y=r.useRef(null),v=r.useRef(null);r.useLayoutEffect((()=>{const r=y.current;if(!r)return;const i=u.fontMetadata.fontScale,s=(u.fontMetadata.boundingBox.yMax-u.fontMetadata.boundingBox.yMin+u.fontMetadata.underlineThickness)*i,l=new Float32Array(t.length),c=new Float32Array(2*t.length);let h=0,f=0;const d=[];Array.from(t).forEach(((e,t)=>{if("\n"===e)d.push(h),h=0,f-=s;else{var n;const r=u.fontMetadata.charToIndex[e],o=null!==(n=u.fontMetadata.advances[r])&&void 0!==n?n:u.fontMetadata.advances[x];l[t]=i,c[2*t]=h,c[2*t+1]=f,h+=o*i}})),d.push(h);const p=Math.max(...d),g=-((u.fontMetadata.boundingBox.yMax-u.fontMetadata.boundingBox.yMin)/2+u.fontMetadata.boundingBox.yMin)*i;Array.from(t).forEach(((e,t)=>{l[t]>0&&(o===le.left&&(c[2*t+1]+=g),o===le.right&&(c[2*t]-=p,c[2*t+1]+=g),o===le.center&&(c[2*t]-=p/2,c[2*t+1]+=g))})),r.geometry.boundingBox||(r.geometry.boundingBox=new e.Box3),r.geometry.boundingSphere||(r.geometry.boundingSphere=new e.Sphere),r.geometry.boundingBox.setFromPoints([new e.Vector3(0,u.fontMetadata.boundingBox.yMin*i,0),new e.Vector3(p,u.fontMetadata.boundingBox.yMax*i,n)]),r.geometry.boundingSphere.setFromPoints([new e.Vector3(0,u.fontMetadata.boundingBox.yMin*i,0),new e.Vector3(p,u.fontMetadata.boundingBox.yMax*i,n)]),o===le.left&&(r.geometry.boundingBox.translate(new e.Vector3(0,g,0)),r.geometry.boundingSphere.translate(new e.Vector3(0,g,0))),o===le.right&&(r.geometry.boundingBox.translate(new e.Vector3(-p,g,0)),r.geometry.boundingSphere.translate(new e.Vector3(-p,g,0))),o===le.center&&(r.geometry.boundingBox.translate(new e.Vector3(-p/2,g,0)),r.geometry.boundingSphere.translate(new e.Vector3(-p/2,g,0)));const b=m.addInstances(t,u,null!=a?a:ue,c,r);return b?(v.current=b,()=>m.removeInstances(b)):void 0}),[t,a,u.fontMetadata,x,n,o,m]),r.useEffect((()=>{v.current&&m.setOpacity(v.current,null!=l?l:1)}),[m,l]);const b=r.useMemo((()=>({getBuffers:()=>v.current&&m.getBuffers(v.current),getPtr:()=>v.current,setGlyphs:e=>{if(!v.current)return;const t=m.getBuffers(v.current);if(!t)return;const n=Array.from(e).map((e=>u.fontMetadata.charToIndex[e]));t.instanceGIndexBuffer.set(n,v.current.start),t.instanceGIndexBufferAttribute.needsUpdate=!0}})),[u.fontMetadata.charToIndex]);return f.createElement("instancedTextPlaceholder",d.default({scale:[i*(null!==(h=null==s?void 0:s.x)&&void 0!==h?h:1),i*(null!==(p=null==s?void 0:s.y)&&void 0!==p?p:1),n*(null!==(g=null==s?void 0:s.z)&&void 0!==g?g:1)]},c,{textAPI:b,ref:y,frustumCulled:!1}))},exports.InstancedTextProvider=function({children:e,styles:t}){r.useMemo(Z,[]);const n=r.useRef(new WeakMap),i=r.useCallback((e=>{e&&n.current.set(e.font,e)}),[]),o=r.useMemo((()=>({addInstances:(e,t,r,i,o)=>{const s=n.current.get(t);return null==s?void 0:s.addInstances(e,t,r,i,o)},removeInstances:e=>{const t=n.current.get(e.font);null==t||t.removeInstances(e)},setOpacity:(e,t)=>{const r=n.current.get(e.font);null==r||r.setOpacity(e,t)},getBuffers:e=>{var t;const r=n.current.get(e.font);return null!==(t=null==r?void 0:r.getBuffers(e))&&void 0!==t?t:null}})),[]);return f.createElement(se.Provider,{value:o},t.map((e=>f.createElement(ae,{key:e.offsetsPath,font:e,ref:i}))),e)},exports.MSDFTextGeometry=E,exports.MSDFTextMaterial=k,exports.SDFText=L,exports.SDFTextProvider=function({children:t,fontPathRegular:n,fontPathBold:i}){r.useMemo(D,[]),f.useEffect((()=>{console.log("Hello, World! This is a SABO fork of thomas engine.")}),[]);const l=o.useTexture(n.sdfPath),u=s.useLoader(a.FontLoader,n.fontPath),c=o.useTexture(i?i.sdfPath:[]),h=s.useLoader(a.FontLoader,i?i.fontPath:[]),d=r.useState((()=>new Map))[0],p=r.useState(0)[1],g=r.useMemo((()=>({insertInstance(t,n,r,i,o){var s;const a={instanceKey:r,config:i,object:o,transform:new e.Matrix4},l=d.get(t);return d.set(t,{textStyle:n,instances:[...null!==(s=null==l?void 0:l.instances)&&void 0!==s?s:[],a]}),p((e=>e+1)),a},removeInstance(e,t){const n=d.get(e);if(n){const r=n.instances.filter((e=>e.instanceKey!==t));0===r.length?d.delete(e):d.set(e,{textStyle:n.textStyle,instances:r}),p((e=>e+1))}}})),[]);return f.createElement(H.Provider,{value:g},f.createElement(f.Fragment,null,t,Array.from(d.values()).map((e=>f.createElement(Y,{key:V(e.textStyle),textStyle:e.textStyle,instances:e.instances,atlas:l,font:u,atlasBold:Array.isArray(c)?void 0:c,fontBold:Array.isArray(h)?void 0:h})))))};
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("three"),t=require("quad-indices"),n=require("word-wrapper"),r=require("react"),i=require("@babel/runtime/helpers/extends"),o=require("@react-three/drei"),s=require("@react-three/fiber"),a=require("three/examples/jsm/loaders/FontLoader");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var c=l(t),h=l(n),d=u(r),f=l(i);const p=["x","e","a","o","n","s","r","c","u","m","v","w","z"],g=["m","w"],m=["H","I","N","E","F","K","L","T","U","V","W","X","Y","Z"],y="\t".charCodeAt(0),x=" ".charCodeAt(0),v=1,b=2;class S{_options={};_width=0;_height=0;_descender=0;_ascender=0;_xHeight=0;_baseline=0;_capHeight=0;_lineHeight=0;_linesTotal=0;_lettersTotal=0;_wordsTotal=0;_fallbackSpaceGlyph=null;_fallbackTabGlyph=null;constructor(e,t={}){this.glyphs=[],this._text=e,this._measure=this.computeMetrics.bind(this),this.update(t)}get width(){return this._width}get height(){return this._height}get descender(){return this._descender}get ascender(){return this._ascender}get xHeight(){return this._xHeight}get baseline(){return this._baseline}get capHeight(){return this._capHeight}get lineHeight(){return this._lineHeight}get linesTotal(){return this._linesTotal}get lettersTotal(){return this._lettersTotal}get wordsTotal(){return this._wordsTotal}update(e){if(e=Object.assign({measure:this._measure},e),this._options=e,this._options.tabSize=I(this._options.tabSize,4),!e.font)throw new Error("must provide a valid bitmap font");const t=this.glyphs,n=this._text||"",r=e.font;this._setupSpaceGlyphs(r);const i=h.default.lines(n,e),o=e.width||0,s=n.split(" ").filter((e=>"\n"!==e)).length,a=n.split("").filter((e=>"\n"!==e&&" "!==e)).length;t.length=0;const l=i.reduce((function(e,t){return Math.max(e,t.width,o)}),0);let u=0,c=0;const d=I(e.lineHeight,r.common.lineHeight),f=r.common.base,g=d-f,y=e.letterSpacing||0,S=d*i.length-g,A=function(e){if("center"===e)return v;if("right"===e)return b;return 0}(this._options.alignX);c-=S,this._width=l,this._height=S,this._descender=d-f,this._baseline=f,this._xHeight=function(e){var t,n;return null!==(t=null==(n=_(e,p))?void 0:n.height)&&void 0!==t?t:0}(r),this._capHeight=function(e){var t,n;return null!==(t=null==(n=_(e,m))?void 0:n.height)&&void 0!==t?t:0}(r),this._lineHeight=d,this._ascender=d-g-this._xHeight;let w=0,M=0;i.forEach(((e,o)=>{const h=e.start,f=e.end,p=e.width,g=n.slice(h,f).split(" ").filter((e=>""!==e)).length,m=n.slice(h,f).split(" ").join("").length;let S,B=0,_=0;for(let e=h;e<f;e++){const h=n.charCodeAt(e),d=this.getGlyph(r,h);if(d){S&&(u+=C(r,S.id,d.id));let n=u;A===v?n+=(l-p)/2:A===b&&(n+=l-p),t.push({position:[n,c],data:d,index:e,linesTotal:i.length,lineIndex:o,lineLettersTotal:m,lineLetterIndex:B,lineWordsTotal:g,lineWordIndex:_,wordsTotal:s,wordIndex:w,lettersTotal:a,letterIndex:M}),d.id===x&&S.id!==x&&(_++,w++),d.id!==x&&(B++,M++),u+=d.xadvance+y,S=d}}c+=d,u=0})),this._lettersTotal=a,this._wordsTotal=s,this._linesTotal=i.length}getGlyph(e,t){const n=B(e,t);return n||(t===y?this._fallbackTabGlyph:t===x?this._fallbackSpaceGlyph:null)}computeMetrics(e,t,n,r){const i=this._options.letterSpacing||0,o=this._options.font;let s,a,l=0,u=0,c=0;if(!o.chars||0===o.chars.length)return{start:t,end:t,width:0};n=Math.min(e.length,n);for(let h=t;h<n;h++){const t=e.charCodeAt(h);if(s=this.getGlyph(o,t),s){s.char=e[h];l+=a?C(o,a.id,s.id):0;const t=l+s.xadvance+i,n=l+s.width;if(n>=r||t>=r)break;l=t,u=n,a=s}c++}return a&&(u+=a.xoffset),{start:t,end:t+c,width:u}}_setupSpaceGlyphs(e){var t;if(this._fallbackSpaceGlyph=null,this._fallbackTabGlyph=null,!e.chars||0===e.chars.length)return;const n=B(e,x)||function(e){var t;return null!==(t=_(e,g))&&void 0!==t?t:0}(e)||e.chars[0],r=(null!==(t=this._options.tabSize)&&void 0!==t?t:1)*n.xadvance;this._fallbackSpaceGlyph=n;const i=Object.assign({},n);this._fallbackTabGlyph=Object.assign(i,{x:0,y:0,xadvance:r,id:y,xoffset:0,yoffset:0,width:0,height:0})}}const A=1114112,w=new WeakMap;function M(e){let t=w.get(e);if(t)return t;t={glyphs:new Map,kernings:new Map};for(const r of null!==(n=e.chars)&&void 0!==n?n:[]){var n;t.glyphs.has(r.id)||t.glyphs.set(r.id,r)}for(const n of null!==(r=e.kernings)&&void 0!==r?r:[]){var r;const e=n.first*A+n.second;t.kernings.has(e)||t.kernings.set(e,n.amount)}return w.set(e,t),t}function B(e,t){var n;return null!==(n=M(e).glyphs.get(t))&&void 0!==n?n:null}function _(e,t){const{glyphs:n}=M(e);for(const e of t){const t=n.get(e.charCodeAt(0));if(t)return t}return null}function C(e,t,n){var r;return null!==(r=M(e).kernings.get(t*A+n))&&void 0!==r?r:0}function I(e,t){return"number"==typeof e?e:"number"==typeof t?t:0}const T=3,F={min:[0,0,0],max:[0,0,0]};function G(e){const t=e.length/T;F.min[0]=e[0],F.min[1]=e[1],F.max[0]=e[0],F.max[1]=e[1];for(let n=0;n<t;n++){const t=e[n*T+0],r=e[n*T+1],i=e[n*T+2];F.min[0]=Math.min(t,F.min[0]),F.min[1]=Math.min(r,F.min[1]),F.min[2]=Math.min(i,F.min[2]),F.max[0]=Math.max(t,F.max[0]),F.max[1]=Math.max(r,F.max[1]),F.max[2]=Math.max(i,F.max[2])}}function P(e,t){return G(e),t.min.set(F.min[0],F.min[1],F.min[2]),t.max.set(F.max[0],F.max[1],F.max[2]),t}function O(e,t,n,r){const i=new Float32Array(4*e.length*2),o=new Float32Array(4*e.length*3),s=new Float32Array(4*e.length*2);let a=0,l=0,u=0;return e.forEach((function(e){const c=e.data,h=c.x+c.width,d=c.y+c.height,f=c.x/t;let p=c.y/n;const g=h/t;let m=d/n;r&&(p=(n-c.y)/n,m=(n-d)/n),i[a++]=f,i[a++]=p,i[a++]=f,i[a++]=m,i[a++]=g,i[a++]=m,i[a++]=g,i[a++]=p;const y=e.position[0]+c.xoffset,x=e.position[1]+c.yoffset,v=c.width,b=c.height;o[l++]=y,o[l++]=x,o[l++]=0,o[l++]=y,o[l++]=x+b,o[l++]=0,o[l++]=y+v,o[l++]=x+b,o[l++]=0,o[l++]=y+v,o[l++]=x,o[l++]=0,s[u++]=y+v/2,s[u++]=x+b/2,s[u++]=y+v/2,s[u++]=x+b/2,s[u++]=y+v/2,s[u++]=x+b/2,s[u++]=y+v/2,s[u++]=x+b/2})),{uvs:i,positions:o,centers:s}}const k=new e.Vector3,E=new e.Vector3,H=new e.Vector3,V=new e.Vector3,L=["text","width","lineHeight","letterSpacing","alignX","alignY","yShift","tabSize"];function j(e){return JSON.stringify(L.map((t=>e[t])))}function D(e,t,n,r){const i=function(e,t){return new S(e,t)}(e.text,e),o=i.glyphs.filter((({data:e})=>e.width*e.height>0));return{layout:i,glyphCount:o.length,...O(o,t,n,r)}}class U extends e.BufferGeometry{originalPositionsArray=new Float32Array;positionsArray=new Float32Array;centersArray=new Float32Array;uvsArray=new Float32Array;positionsAttribute=null;instancesOffsetsCache=[];instancesLengthsCache=[];cache=new Map;cacheFont=null;cacheFlipY=!0;signature=null;glyphsTotal=-1;appliedTransforms=[];constructor(e){super(),this._layouts=[],this.update(e)}setTransform(t,n=0){const r=this.instancesOffsetsCache[n],i=this.instancesLengthsCache[n],o=this.appliedTransforms[n];if(void 0===i||null!=o&&o.equals(t))return!1;for(let e=0;e<i;e++){const n=12*r+12*e,i=this.originalPositionsArray[n],o=this.originalPositionsArray[n+1],s=this.originalPositionsArray[n+2],a=this.originalPositionsArray[n+3],l=this.originalPositionsArray[n+4],u=this.originalPositionsArray[n+5],c=this.originalPositionsArray[n+6],h=this.originalPositionsArray[n+7],d=this.originalPositionsArray[n+8],f=this.originalPositionsArray[n+9],p=this.originalPositionsArray[n+10],g=this.originalPositionsArray[n+11];k.set(i,o,s).applyMatrix4(t),E.set(a,l,u).applyMatrix4(t),H.set(c,h,d).applyMatrix4(t),V.set(f,p,g).applyMatrix4(t),this.positionsArray[n]=k.x,this.positionsArray[n+1]=k.y,this.positionsArray[n+2]=k.z,this.positionsArray[n+3]=E.x,this.positionsArray[n+4]=E.y,this.positionsArray[n+5]=E.z,this.positionsArray[n+6]=H.x,this.positionsArray[n+7]=H.y,this.positionsArray[n+8]=H.z,this.positionsArray[n+9]=V.x,this.positionsArray[n+10]=V.y,this.positionsArray[n+11]=V.z}return this.appliedTransforms[n]=(null!=o?o:new e.Matrix4).copy(t),this.positionsAttribute&&(this.positionsAttribute.needsUpdate=!0),!0}update(t){const{texts:n,...r}=t,i=t.font,o=!1!==t.flipY;i===this.cacheFont&&o===this.cacheFlipY||(this.cache.clear(),this.cacheFont=i,this.cacheFlipY=o,this.signature=null);const s=n.map((e=>({...r,...e}))),a=s.map(j),l=a.join("\n");if(l===this.signature)return;this.signature=l;const u=i.common.scaleW,h=i.common.scaleH,d=s.map(((e,t)=>{var n;const r=a[t],i=null!==(n=this.cache.get(r))&&void 0!==n?n:D(e,u,h,o);return this.cache.delete(r),this.cache.set(r,i),i}));for(const e of this.cache.keys()){if(this.cache.size<=n.length+256)break;this.cache.delete(e)}this._layouts=d.map((e=>e.layout)),this.instancesOffsetsCache=[],this.instancesLengthsCache=[];let f=0;d.forEach((({glyphCount:e},t)=>{this.instancesLengthsCache[t]=e,this.instancesOffsetsCache[t]=f,f+=e}));const p=f;this.appliedTransforms=[],p!==this.glyphsTotal&&(this.glyphsTotal=p,this.setIndex(c.default([],{clockwise:!0,type:"uint16",count:p})),this.positionsArray=new Float32Array(12*p),this.originalPositionsArray=new Float32Array(12*p),this.centersArray=new Float32Array(8*p),this.uvsArray=new Float32Array(8*p),this.positionsAttribute=new e.BufferAttribute(this.positionsArray,3),this.setAttribute("position",this.positionsAttribute),this.setAttribute("center",new e.BufferAttribute(this.centersArray,2)),this.setAttribute("uv",new e.BufferAttribute(this.uvsArray,2))),d.forEach(((e,t)=>{const n=this.instancesOffsetsCache[t];this.positionsArray.set(e.positions,12*n),this.centersArray.set(e.centers,8*n),this.uvsArray.set(e.uvs,8*n)})),this.originalPositionsArray.set(this.positionsArray);for(const e of["position","center","uv"])this.attributes[e].needsUpdate=!0}dispose(){this.cache.clear(),this.appliedTransforms=[],this.signature=null,super.dispose()}computeBoundingSphere(){null===this.boundingSphere&&(this.boundingSphere=new e.Sphere);const t=this.attributes.position.array,n=this.attributes.position.itemSize;if(!t||!n||t.length<2)return this.boundingSphere.radius=0,void this.boundingSphere.center.set(0,0,0);!function(e,t){G(e);const n=F.min[0],r=F.min[1],i=F.min[2],o=F.max[0]-n,s=F.max[1]-r,a=F.max[2]-i,l=Math.sqrt(o*o+s*s+a*a);t.center.set(n+o/2,r+s/2,i+a/2),t.radius=l/2}(t,this.boundingSphere),isNaN(this.boundingSphere.radius)&&console.error('BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.')}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new e.Box3);const t=this.boundingBox,n=this.attributes.position.array,r=this.attributes.position.itemSize;if(!n||!r||n.length<2)return void t.makeEmpty();return P(n,t)}}class W extends e.ShaderMaterial{constructor(t={}){super(t={...{side:e.FrontSide,transparent:!0,extensions:{derivatives:!0},uniforms:{uOpacity:{value:1},uOffset:{value:0},uColor:{value:new e.Color("#ffffff")},uMap:{value:null}},vertexShader:"#define GLSLIFY 1\nvarying vec2 vUv;void main(){vec4 mvPosition=vec4(position,1.0);mvPosition=modelViewMatrix*mvPosition;gl_Position=projectionMatrix*mvPosition;vUv=uv;}",fragmentShader:"#define GLSLIFY 1\nvarying vec2 vUv;uniform float uOpacity;uniform float uOffset;uniform vec3 uColor;uniform sampler2D uMap;float median(float r,float g,float b){return max(min(r,g),min(max(r,g),b));}void main(){vec3 s=texture2D(uMap,vUv).rgb;float sigDist=median(s.r,s.g,s.b)-0.5+uOffset;float alpha=clamp(sigDist/fwidth(sigDist)+0.5,0.0,1.0);if(alpha<0.01)discard;gl_FragColor=vec4(uColor,uOpacity*alpha);}"},...t})}}const z=r.createContext(null),N=e=>{var t,n;return[e.bold,null==(t=e.color)?void 0:t.getHexString(),e.opacity,e.outlineWidth,e.outlineOpacity,null==(n=e.outlineColor)?void 0:n.getHexString()].join("_")},Y=r.forwardRef((function({instanceKey:e,bold:t,color:n,opacity:i,outlineWidth:o,outlineOpacity:s,outlineColor:a,text:l,alignX:u,alignY:c,letterSpacing:h,yShift:f,width:p,lineHeight:g,onBeforeUpdate:m},y){const x=r.useContext(z);if(!x)throw new Error("No SDFTextProvider");const v=r.useRef(null),b=r.useRef(null);return r.useImperativeHandle(y,(()=>({setTransform(e){b.current&&(b.current.transform=e)}})),[]),r.useLayoutEffect((()=>{var r;const d={bold:t,color:n,opacity:i,outlineWidth:o,outlineOpacity:s,outlineColor:a},y={text:l,alignX:u,alignY:c,letterSpacing:h,yShift:f,width:p,lineHeight:g,onBeforeUpdate:m},S=N(d);return b.current=x.insertInstance(S,d,e,y,null!==(r=v.current)&&void 0!==r?r:void 0),()=>x.removeInstance(S,e)}),[x,e,l,u,c,h,f,p,g,t,n,i,o,s,a,m]),d.createElement("group",{ref:v})}));function q(){s.extend({MSDFTextMaterial:W,MSDFTextGeometry:U})}const R=99999,X=99998,K=new e.Matrix4,J=new e.Matrix4,Z=new e.Color("#ffffff"),Q=new e.Color("#000000"),$=.01;function ee({instances:e,textStyle:t,atlas:n,font:i,atlasBold:o,fontBold:a,...l}){var u;const c=o&&a&&t.bold,h=c?a.data:i.data,p=r.useState((()=>new U({font:h,texts:[]})))[0];r.useLayoutEffect((()=>()=>p.dispose()),[p]),r.useLayoutEffect((()=>{const t=e.map((e=>e.config));p.update({font:h,texts:t})}),[p,e,h]),s.useFrame((()=>{e.forEach(((t,n)=>{null==t.config.onBeforeUpdate||t.config.onBeforeUpdate(),J.identity();const r=e[n].object;r&&(r.updateMatrixWorld(),J.multiply(r.matrixWorld)),J.multiply(t.transform),K.makeScale($,$,$),J.multiply(K);const i=p._layouts[n];if(i){var o,s,a,l;const e=null!==(o=i.width)&&void 0!==o?o:0,t=null!==(s=i.height)&&void 0!==s?s:0,n=null!==(a=i.lineHeight)&&void 0!==a?a:0,r=null!==(l=i._options.yShift)&&void 0!==l?l:0,u=n/4-t,c=n/2;let h=0;"center"===i._options.alignX&&(h=-e/2),"right"===i._options.alignX&&(h=-e);let d=u+r;"middle"===i._options.alignY&&(d=(u+c)/2-i.ascender+r),"bottom"===i._options.alignY&&(d=c+r),K.makeTranslation(h,d,0),J.multiply(K)}K.makeRotationX(Math.PI),J.multiply(K),p.setTransform(J,n)}))}));const g=r.useMemo((()=>{var e,r;return{uMap:{value:c?o:n},uColor:{value:null!==(e=t.color)&&void 0!==e?e:Z},uOpacity:{value:null!==(r=t.opacity)&&void 0!==r?r:1},uOffset:{value:0}}}),[c,t.opacity,t.color,n,o]),m=r.useMemo((()=>{var e,r;return{uMap:{value:c?o:n},uColor:{value:null!==(e=t.outlineColor)&&void 0!==e?e:Q},uOpacity:{value:null!==(r=t.outlineOpacity)&&void 0!==r?r:.4},uOffset:{value:t.outlineWidth}}}),[c,t.outlineOpacity,t.outlineColor,t.outlineWidth,n,o]);return d.createElement(d.Fragment,null,d.createElement("mesh",f.default({geometry:p,frustumCulled:!1,renderOrder:R},l),d.createElement("mSDFTextMaterial",{uniforms:g})),(null!==(u=t.outlineWidth)&&void 0!==u?u:0)>0&&d.createElement("mesh",f.default({geometry:p,frustumCulled:!1,renderOrder:X},l),d.createElement("mSDFTextMaterial",{uniforms:m,depthWrite:!1})))}const te=new e.Matrix4,ne=new e.Matrix4;function re(){s.extend({InstancedTextPlaceholder:ue})}class ie{boundingBox=null;boundingSphere=null;computeBoundingBox(){this.boundingBox||(this.boundingBox=new e.Box3)}computeBoundingSphere(){this.boundingSphere||(this.boundingSphere=new e.Sphere)}}const oe=new e.Matrix4,se=new e.Ray,ae=new e.Sphere,le=new e.Vector3;class ue extends e.Group{textAPI=void 0;geometry=new ie;raycast(e,t){const n=this.geometry,r=this.matrixWorld;null===n.boundingSphere&&n.computeBoundingSphere(),ae.copy(n.boundingSphere),ae.applyMatrix4(r),!1!==e.ray.intersectsSphere(ae)&&(oe.copy(r).invert(),se.copy(e.ray).applyMatrix4(oe),null!==n.boundingBox&&null===se.intersectBox(n.boundingBox,le)||t.push({distance:le.distanceTo(e.ray.origin),point:le.clone(),object:this}))}}const ce=()=>new e.MeshPhongMaterial;function he(t,n,i,o=ce){return r.useMemo((()=>{const r=o();return r.onBeforeCompile=r=>{r.uniforms={...r.uniforms,offsets:{value:t},normals:{value:n},shift:{value:new e.Vector3(i.xShift,i.yShift,i.zShift)},scale:{value:new e.Vector3(i.xScale,i.yScale,i.zScale)}},r.vertexShader=r.vertexShader.replace(/#include <morphtarget_pars_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <morphtarget_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <morphcolor_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <morphnormal_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <skinning_pars_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <skinbase_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <skinning_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <skinnormal_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <displacementmap_pars_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/#include <displacementmap_vertex>/gi,""),r.vertexShader=r.vertexShader.replace(/>[\n]*void/,">\n uniform sampler2D offsets;\n uniform sampler2D normals;\n uniform vec3 shift;\n uniform vec3 scale;\n in float instanceGIndex;\n\n void"),r.vertexShader=r.vertexShader.replace(/void main\(\) {/,"void main() { vec3 offset = texelFetch(offsets, ivec2(gl_VertexID, instanceGIndex), 0).rgb * scale + shift;"),r.vertexShader=r.vertexShader.replace(/#include <beginnormal_vertex>/,"vec3 objectNormal = (texelFetch(normals, ivec2(gl_VertexID, instanceGIndex), 0).rgb) - 0.5;"),r.vertexShader=r.vertexShader.replace(/#include <begin_vertex>/,"vec3 transformed = offset;")},r}),[t,n,i,o])}function de(t){const n=o.useTexture(t);return n.flipY=!1,n.magFilter=e.NearestFilter,n.minFilter=e.NearestFilter,n}const fe=r.createContext(null);const pe=r.forwardRef((function({font:t},n){const i=he(de(t.offsetsPath),de(t.normalsPath),t.fontMetadata),[{instanceAllocated:o,geometry:a},l]=r.useState({instanceAllocated:0,geometry:null}),u=r.useRef(null),c=r.useCallback((n=>(u.current=function(t,n,r){var i,o,s,a;null==t||t.geometry.dispose();const l=new e.InstancedBufferGeometry;l.instanceCount=n;const u=new Float32Array(3*r),c=new e.Float32BufferAttribute(u,3,!1);l.setAttribute("position",c);const h=new Float32Array(16*l.instanceCount),d=new e.InstancedBufferAttribute(h,16,!1,1);l.setAttribute("instanceMatrix",d);const f=new Float32Array(l.instanceCount);t&&f.set(t.currentGlyphs);const p=new e.InstancedBufferAttribute(f,1,!1,1);l.setAttribute("instanceGIndex",p);const g=new Float32Array(4*l.instanceCount);t&&g.set(t.currentColors);const m=new e.InstancedBufferAttribute(g,4,!0,1);return l.setAttribute("instanceColor",m),{instanceAllocated:n,geometry:l,currentInstances:null!==(i=null==t?void 0:t.currentInstances)&&void 0!==i?i:[],currentGlyphs:null!==(o=null==t?void 0:t.currentGlyphs)&&void 0!==o?o:[],currentShifts:null!==(s=null==t?void 0:t.currentShifts)&&void 0!==s?s:[],currentColors:null!==(a=null==t?void 0:t.currentColors)&&void 0!==a?a:[],instanceMatrixBuffer:h,instanceMatrixBufferAttribute:d,instanceGIndexBuffer:f,instanceGIndexBufferAttribute:p,instanceColorBuffer:g,instanceColorBufferAttribute:m}}(u.current,n,t.fontMetadata.maxVertices),l({instanceAllocated:n,geometry:u.current.geometry}),u.current)),[t.fontMetadata.maxVertices]);return r.useImperativeHandle(n,(()=>({font:t,addInstances:(e,t,n,r,i)=>{var o;const s=null!==(o=u.current)&&void 0!==o?o:c(2*e.length),a=function(e,t,n,r,i,o,s){const a=e.currentGlyphs.length,l=n.length,u=Array.from(n).map((e=>t[e])),c=Array.from(n).flatMap((()=>[i.r,i.g,i.b,1]));e.currentGlyphs.push(...u),e.currentShifts.push(...o),e.currentColors.push(...c);const h={start:a,length:l,text:n,parentGroup:s,font:r};return e.currentInstances.push(h),h}(s,t.fontMetadata.charToIndex,e,t,n,r,i);return s.currentGlyphs.length>s.instanceAllocated?c(2*s.currentGlyphs.length):function(e){e.instanceGIndexBuffer.set(e.currentGlyphs),e.instanceGIndexBufferAttribute.needsUpdate=!0,e.instanceColorBuffer.set(e.currentColors),e.instanceColorBufferAttribute.needsUpdate=!0}(s),a},removeInstances:e=>{const t=u.current;t&&function(e,t){const n=e.currentInstances.indexOf(t);if(-1!==n){for(let r=0;r<e.currentInstances.length;r++)r>n&&(e.currentInstances[r].start-=t.length);e.currentInstances.splice(n,1),e.currentGlyphs.splice(t.start,t.length),e.currentShifts.splice(2*t.start,2*t.length),e.currentColors.splice(4*t.start,4*t.length),e.instanceGIndexBuffer.fill(0),e.instanceGIndexBuffer.set(e.currentGlyphs),e.instanceGIndexBufferAttribute.needsUpdate=!0,e.instanceColorBuffer.fill(0),e.instanceColorBuffer.set(e.currentColors),e.instanceColorBufferAttribute.needsUpdate=!0,e.instanceMatrixBuffer.fill(0),e.instanceMatrixBufferAttribute.needsUpdate=!0}}(t,e)},setOpacity:(e,t)=>{const n=u.current;if(n&&n.instanceColorBuffer&&n.instanceColorBufferAttribute){for(let r=0;r<e.length;r++)n.currentColors[4*(e.start+r)+3]=t,n.instanceColorBuffer[4*(e.start+r)+3]=t;n.instanceColorBufferAttribute.needsUpdate=!0}},getBuffers:()=>u.current})),[t,c]),s.useFrame((()=>{const e=u.current;e&&function(e){e.currentInstances.forEach((t=>{for(let n=0;n<t.length;n++){const r=e.currentShifts[2*(t.start+n)],i=e.currentShifts[2*(t.start+n)+1];ne.copy(t.parentGroup.matrixWorld),te.identity().setPosition(r,i,0),ne.multiply(te),ne.toArray(e.instanceMatrixBuffer,16*(t.start+n))}})),e.instanceMatrixBufferAttribute.needsUpdate=!0}(e)})),a?d.createElement("instancedMesh",{frustumCulled:!1,args:[a,i,o]}):null}));let ge=function(e){return e.left="left",e.right="right",e.center="center",e}({});const me=new e.Color("white");exports.InstancedText=function({text:t,thickness:n,fontSize:i,textAlign:o,scale:s,color:a,opacity:l,font:u,...c}){var h,p,g;const m=u.fontMetadata.charToIndex["?"],y=function(){const e=r.useContext(fe);if(!e)throw new Error("No instanced text context");return e}(),x=r.useRef(null),v=r.useRef(null);r.useLayoutEffect((()=>{const r=x.current;if(!r)return;const i=u.fontMetadata.fontScale,s=(u.fontMetadata.boundingBox.yMax-u.fontMetadata.boundingBox.yMin+u.fontMetadata.underlineThickness)*i,l=new Float32Array(t.length),c=new Float32Array(2*t.length);let h=0,d=0;const f=[];Array.from(t).forEach(((e,t)=>{if("\n"===e)f.push(h),h=0,d-=s;else{var n;const r=u.fontMetadata.charToIndex[e],o=null!==(n=u.fontMetadata.advances[r])&&void 0!==n?n:u.fontMetadata.advances[m];l[t]=i,c[2*t]=h,c[2*t+1]=d,h+=o*i}})),f.push(h);const p=Math.max(...f),g=-((u.fontMetadata.boundingBox.yMax-u.fontMetadata.boundingBox.yMin)/2+u.fontMetadata.boundingBox.yMin)*i;Array.from(t).forEach(((e,t)=>{l[t]>0&&(o===ge.left&&(c[2*t+1]+=g),o===ge.right&&(c[2*t]-=p,c[2*t+1]+=g),o===ge.center&&(c[2*t]-=p/2,c[2*t+1]+=g))})),r.geometry.boundingBox||(r.geometry.boundingBox=new e.Box3),r.geometry.boundingSphere||(r.geometry.boundingSphere=new e.Sphere),r.geometry.boundingBox.setFromPoints([new e.Vector3(0,u.fontMetadata.boundingBox.yMin*i,0),new e.Vector3(p,u.fontMetadata.boundingBox.yMax*i,n)]),r.geometry.boundingSphere.setFromPoints([new e.Vector3(0,u.fontMetadata.boundingBox.yMin*i,0),new e.Vector3(p,u.fontMetadata.boundingBox.yMax*i,n)]),o===ge.left&&(r.geometry.boundingBox.translate(new e.Vector3(0,g,0)),r.geometry.boundingSphere.translate(new e.Vector3(0,g,0))),o===ge.right&&(r.geometry.boundingBox.translate(new e.Vector3(-p,g,0)),r.geometry.boundingSphere.translate(new e.Vector3(-p,g,0))),o===ge.center&&(r.geometry.boundingBox.translate(new e.Vector3(-p/2,g,0)),r.geometry.boundingSphere.translate(new e.Vector3(-p/2,g,0)));const b=y.addInstances(t,u,null!=a?a:me,c,r);return b?(v.current=b,()=>y.removeInstances(b)):void 0}),[t,a,u.fontMetadata,m,n,o,y]),r.useEffect((()=>{v.current&&y.setOpacity(v.current,null!=l?l:1)}),[y,l]);const b=r.useMemo((()=>({getBuffers:()=>v.current&&y.getBuffers(v.current),getPtr:()=>v.current,setGlyphs:e=>{if(!v.current)return;const t=y.getBuffers(v.current);if(!t)return;const n=Array.from(e).map((e=>u.fontMetadata.charToIndex[e]));t.instanceGIndexBuffer.set(n,v.current.start),t.instanceGIndexBufferAttribute.needsUpdate=!0}})),[u.fontMetadata.charToIndex]);return d.createElement("instancedTextPlaceholder",f.default({scale:[i*(null!==(h=null==s?void 0:s.x)&&void 0!==h?h:1),i*(null!==(p=null==s?void 0:s.y)&&void 0!==p?p:1),n*(null!==(g=null==s?void 0:s.z)&&void 0!==g?g:1)]},c,{textAPI:b,ref:x,frustumCulled:!1}))},exports.InstancedTextProvider=function({children:e,styles:t}){r.useMemo(re,[]);const n=r.useRef(new WeakMap),i=r.useCallback((e=>{e&&n.current.set(e.font,e)}),[]),o=r.useMemo((()=>({addInstances:(e,t,r,i,o)=>{const s=n.current.get(t);return null==s?void 0:s.addInstances(e,t,r,i,o)},removeInstances:e=>{const t=n.current.get(e.font);null==t||t.removeInstances(e)},setOpacity:(e,t)=>{const r=n.current.get(e.font);null==r||r.setOpacity(e,t)},getBuffers:e=>{var t;const r=n.current.get(e.font);return null!==(t=null==r?void 0:r.getBuffers(e))&&void 0!==t?t:null}})),[]);return d.createElement(fe.Provider,{value:o},t.map((e=>d.createElement(pe,{key:e.offsetsPath,font:e,ref:i}))),e)},exports.MSDFTextGeometry=U,exports.MSDFTextMaterial=W,exports.SDFText=Y,exports.SDFTextProvider=function({children:t,fontPathRegular:n,fontPathBold:i}){r.useMemo(q,[]),d.useEffect((()=>{console.log("Hello, World! This is a SABO fork of thomas engine.")}),[]);const l=o.useTexture(n.sdfPath),u=s.useLoader(a.FontLoader,n.fontPath),c=o.useTexture(i?i.sdfPath:[]),h=s.useLoader(a.FontLoader,i?i.fontPath:[]),f=r.useState((()=>new Map))[0],p=r.useState(0)[1],g=r.useMemo((()=>({insertInstance(t,n,r,i,o){var s;const a={instanceKey:r,config:i,object:o,transform:new e.Matrix4},l=f.get(t);return f.set(t,{textStyle:n,instances:[...null!==(s=null==l?void 0:l.instances)&&void 0!==s?s:[],a]}),p((e=>e+1)),a},removeInstance(e,t){const n=f.get(e);if(n){const r=n.instances.filter((e=>e.instanceKey!==t));0===r.length?f.delete(e):f.set(e,{textStyle:n.textStyle,instances:r}),p((e=>e+1))}}})),[]);return d.createElement(z.Provider,{value:g},d.createElement(d.Fragment,null,t,Array.from(f.values()).map((e=>d.createElement(ee,{key:N(e.textStyle),textStyle:e.textStyle,instances:e.instances,atlas:l,font:u,atlasBold:Array.isArray(c)?void 0:c,fontBold:Array.isArray(h)?void 0:h})))))};
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";function t(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}Object.defineProperty(exports,"__esModule",{value:!0});var e=t(require("word-wrapper"));const n=["x","e","a","o","n","s","r","c","u","m","v","w","z"],i=["m","w"],
|
|
1
|
+
"use strict";function t(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}Object.defineProperty(exports,"__esModule",{value:!0});var e=t(require("word-wrapper"));const n=["x","e","a","o","n","s","r","c","u","m","v","w","z"],i=["m","w"],s=["H","I","N","E","F","K","L","T","U","V","W","X","Y","Z"],r="\t".charCodeAt(0),l=" ".charCodeAt(0),h=1,o=2;class a{_options={};_width=0;_height=0;_descender=0;_ascender=0;_xHeight=0;_baseline=0;_capHeight=0;_lineHeight=0;_linesTotal=0;_lettersTotal=0;_wordsTotal=0;_fallbackSpaceGlyph=null;_fallbackTabGlyph=null;constructor(t,e={}){this.glyphs=[],this._text=t,this._measure=this.computeMetrics.bind(this),this.update(e)}get width(){return this._width}get height(){return this._height}get descender(){return this._descender}get ascender(){return this._ascender}get xHeight(){return this._xHeight}get baseline(){return this._baseline}get capHeight(){return this._capHeight}get lineHeight(){return this._lineHeight}get linesTotal(){return this._linesTotal}get lettersTotal(){return this._lettersTotal}get wordsTotal(){return this._wordsTotal}update(t){if(t=Object.assign({measure:this._measure},t),this._options=t,this._options.tabSize=_(this._options.tabSize,4),!t.font)throw new Error("must provide a valid bitmap font");const i=this.glyphs,r=this._text||"",a=t.font;this._setupSpaceGlyphs(a);const c=e.default.lines(r,t),u=t.width||0,d=r.split(" ").filter((t=>"\n"!==t)).length,g=r.split("").filter((t=>"\n"!==t&&" "!==t)).length;i.length=0;const b=c.reduce((function(t,e){return Math.max(t,e.width,u)}),0);let v=0,w=0;const y=_(t.lineHeight,a.common.lineHeight),x=a.common.base,T=y-x,m=t.letterSpacing||0,H=y*c.length-T,k=function(t){if("center"===t)return h;if("right"===t)return o;return 0}(this._options.alignX);w-=H,this._width=b,this._height=H,this._descender=y-x,this._baseline=x,this._xHeight=function(t){var e,i;return null!==(e=null==(i=p(t,n))?void 0:i.height)&&void 0!==e?e:0}(a),this._capHeight=function(t){var e,n;return null!==(e=null==(n=p(t,s))?void 0:n.height)&&void 0!==e?e:0}(a),this._lineHeight=y,this._ascender=y-T-this._xHeight;let G=0,S=0;c.forEach(((t,e)=>{const n=t.start,s=t.end,u=t.width,p=r.slice(n,s).split(" ").filter((t=>""!==t)).length,_=r.slice(n,s).split(" ").join("").length;let x,T=0,H=0;for(let t=n;t<s;t++){const n=r.charCodeAt(t),s=this.getGlyph(a,n);if(s){x&&(v+=f(a,x.id,s.id));let n=v;k===h?n+=(b-u)/2:k===o&&(n+=b-u),i.push({position:[n,w],data:s,index:t,linesTotal:c.length,lineIndex:e,lineLettersTotal:_,lineLetterIndex:T,lineWordsTotal:p,lineWordIndex:H,wordsTotal:d,wordIndex:G,lettersTotal:g,letterIndex:S}),s.id===l&&x.id!==l&&(H++,G++),s.id!==l&&(T++,S++),v+=s.xadvance+m,x=s}}w+=y,v=0})),this._lettersTotal=g,this._wordsTotal=d,this._linesTotal=c.length}getGlyph(t,e){const n=g(t,e);return n||(e===r?this._fallbackTabGlyph:e===l?this._fallbackSpaceGlyph:null)}computeMetrics(t,e,n,i){const s=this._options.letterSpacing||0,r=this._options.font;let l,h,o=0,a=0,c=0;if(!r.chars||0===r.chars.length)return{start:e,end:e,width:0};n=Math.min(t.length,n);for(let u=e;u<n;u++){const e=t.charCodeAt(u);if(l=this.getGlyph(r,e),l){l.char=t[u];o+=h?f(r,h.id,l.id):0;const e=o+l.xadvance+s,n=o+l.width;if(n>=i||e>=i)break;o=e,a=n,h=l}c++}return h&&(a+=h.xoffset),{start:e,end:e+c,width:a}}_setupSpaceGlyphs(t){var e;if(this._fallbackSpaceGlyph=null,this._fallbackTabGlyph=null,!t.chars||0===t.chars.length)return;const n=g(t,l)||function(t){var e;return null!==(e=p(t,i))&&void 0!==e?e:0}(t)||t.chars[0],s=(null!==(e=this._options.tabSize)&&void 0!==e?e:1)*n.xadvance;this._fallbackSpaceGlyph=n;const h=Object.assign({},n);this._fallbackTabGlyph=Object.assign(h,{x:0,y:0,xadvance:s,id:r,xoffset:0,yoffset:0,width:0,height:0})}}const c=1114112,u=new WeakMap;function d(t){let e=u.get(t);if(e)return e;e={glyphs:new Map,kernings:new Map};for(const i of null!==(n=t.chars)&&void 0!==n?n:[]){var n;e.glyphs.has(i.id)||e.glyphs.set(i.id,i)}for(const n of null!==(i=t.kernings)&&void 0!==i?i:[]){var i;const t=n.first*c+n.second;e.kernings.has(t)||e.kernings.set(t,n.amount)}return u.set(t,e),e}function g(t,e){var n;return null!==(n=d(t).glyphs.get(e))&&void 0!==n?n:null}function p(t,e){const{glyphs:n}=d(t);for(const t of e){const e=n.get(t.charCodeAt(0));if(e)return e}return null}function f(t,e,n){var i;return null!==(i=d(t).kernings.get(e*c+n))&&void 0!==i?i:0}function _(t,e){return"number"==typeof t?t:"number"==typeof e?e:0}exports.createLayout=function(t,e){return new a(t,e)},exports.default=a;
|
|
@@ -283,55 +283,67 @@ class TextLayout {
|
|
|
283
283
|
function createLayout(text, options) {
|
|
284
284
|
return new TextLayout(text, options);
|
|
285
285
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
286
|
+
|
|
287
|
+
/** Glyph ids are code points, so a kerning pair packs into one number. */
|
|
288
|
+
const KERNING_STRIDE = 0x110000;
|
|
289
|
+
const fontIndexes = new WeakMap();
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Index a font's glyphs and kerning pairs once.
|
|
293
|
+
*
|
|
294
|
+
* The layout looks up every character and every adjacent pair. A linear scan over a few thousand
|
|
295
|
+
* kerning pairs made that the hottest loop of the engine. The index assumes that font data does
|
|
296
|
+
* not change after it is loaded.
|
|
297
|
+
*/
|
|
298
|
+
function indexFont(font) {
|
|
299
|
+
let index = fontIndexes.get(font);
|
|
300
|
+
if (index) return index;
|
|
301
|
+
index = {
|
|
302
|
+
glyphs: new Map(),
|
|
303
|
+
kernings: new Map()
|
|
304
|
+
};
|
|
305
|
+
// The first entry wins, as it did with the linear scan
|
|
306
|
+
for (const glyph of (_font$chars = font.chars) !== null && _font$chars !== void 0 ? _font$chars : []) {
|
|
307
|
+
var _font$chars;
|
|
308
|
+
if (!index.glyphs.has(glyph.id)) index.glyphs.set(glyph.id, glyph);
|
|
309
|
+
}
|
|
310
|
+
for (const kern of (_font$kernings = font.kernings) !== null && _font$kernings !== void 0 ? _font$kernings : []) {
|
|
311
|
+
var _font$kernings;
|
|
312
|
+
const pair = kern.first * KERNING_STRIDE + kern.second;
|
|
313
|
+
if (!index.kernings.has(pair)) index.kernings.set(pair, kern.amount);
|
|
289
314
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
315
|
+
fontIndexes.set(font, index);
|
|
316
|
+
return index;
|
|
317
|
+
}
|
|
318
|
+
function getGlyphById(font, id) {
|
|
319
|
+
var _indexFont$glyphs$get;
|
|
320
|
+
return (_indexFont$glyphs$get = indexFont(font).glyphs.get(id)) !== null && _indexFont$glyphs$get !== void 0 ? _indexFont$glyphs$get : null;
|
|
321
|
+
}
|
|
322
|
+
function getFirstGlyph(font, chars) {
|
|
323
|
+
const {
|
|
324
|
+
glyphs
|
|
325
|
+
} = indexFont(font);
|
|
326
|
+
for (const char of chars) {
|
|
327
|
+
const glyph = glyphs.get(char.charCodeAt(0));
|
|
328
|
+
if (glyph) return glyph;
|
|
294
329
|
}
|
|
295
330
|
return null;
|
|
296
331
|
}
|
|
297
332
|
function getXHeight(font) {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (idx >= 0) {
|
|
301
|
-
return font.chars[idx].height;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return 0;
|
|
333
|
+
var _getFirstGlyph$height, _getFirstGlyph;
|
|
334
|
+
return (_getFirstGlyph$height = (_getFirstGlyph = getFirstGlyph(font, X_HEIGHTS)) == null ? void 0 : _getFirstGlyph.height) !== null && _getFirstGlyph$height !== void 0 ? _getFirstGlyph$height : 0;
|
|
305
335
|
}
|
|
306
336
|
function getMGlyph(font) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (idx >= 0) {
|
|
310
|
-
return font.chars[idx];
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
return 0;
|
|
337
|
+
var _getFirstGlyph2;
|
|
338
|
+
return (_getFirstGlyph2 = getFirstGlyph(font, M_WIDTHS)) !== null && _getFirstGlyph2 !== void 0 ? _getFirstGlyph2 : 0;
|
|
314
339
|
}
|
|
315
340
|
function getCapHeight(font) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if (idx >= 0) {
|
|
319
|
-
return font.chars[idx].height;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
return 0;
|
|
341
|
+
var _getFirstGlyph$height2, _getFirstGlyph3;
|
|
342
|
+
return (_getFirstGlyph$height2 = (_getFirstGlyph3 = getFirstGlyph(font, CAP_HEIGHTS)) == null ? void 0 : _getFirstGlyph3.height) !== null && _getFirstGlyph$height2 !== void 0 ? _getFirstGlyph$height2 : 0;
|
|
323
343
|
}
|
|
324
344
|
function getKerning(font, left, right) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
const table = font.kernings;
|
|
329
|
-
for (const kern of table) {
|
|
330
|
-
if (kern.first === left && kern.second === right) {
|
|
331
|
-
return kern.amount;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
return 0;
|
|
345
|
+
var _indexFont$kernings$g;
|
|
346
|
+
return (_indexFont$kernings$g = indexFont(font).kernings.get(left * KERNING_STRIDE + right)) !== null && _indexFont$kernings$g !== void 0 ? _indexFont$kernings$g : 0;
|
|
335
347
|
}
|
|
336
348
|
function getAlignType(align) {
|
|
337
349
|
if (align === 'center') {
|
|
@@ -341,15 +353,6 @@ function getAlignType(align) {
|
|
|
341
353
|
}
|
|
342
354
|
return ALIGN_LEFT;
|
|
343
355
|
}
|
|
344
|
-
function findChar(array, value, start) {
|
|
345
|
-
start = start || 0;
|
|
346
|
-
for (let i = start; i < array.length; i++) {
|
|
347
|
-
if (array[i].id === value) {
|
|
348
|
-
return i;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return -1;
|
|
352
|
-
}
|
|
353
356
|
function number(num, def) {
|
|
354
357
|
return typeof num === 'number' ? num : typeof def === 'number' ? def : 0;
|
|
355
358
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=require("quad-indices"),i=require("three"),s=require("./TextLayout.cjs.js"),e=require("./utils.cjs.js"),r=require("./vertices.cjs.js");function
|
|
1
|
+
"use strict";var t=require("quad-indices"),i=require("three"),s=require("./TextLayout.cjs.js"),e=require("./utils.cjs.js"),r=require("./vertices.cjs.js");function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}require("word-wrapper");var o=n(t);const a=new i.Vector3,h=new i.Vector3,u=new i.Vector3,c=new i.Vector3,l=["text","width","lineHeight","letterSpacing","alignX","alignY","yShift","tabSize"];function p(t){return JSON.stringify(l.map((i=>t[i])))}class y extends i.BufferGeometry{originalPositionsArray=new Float32Array;positionsArray=new Float32Array;centersArray=new Float32Array;uvsArray=new Float32Array;positionsAttribute=null;instancesOffsetsCache=[];instancesLengthsCache=[];cache=new Map;cacheFont=null;cacheFlipY=!0;signature=null;glyphsTotal=-1;appliedTransforms=[];constructor(t){super(),this._layouts=[],this.update(t)}setTransform(t,s=0){const e=this.instancesOffsetsCache[s],r=this.instancesLengthsCache[s],n=this.appliedTransforms[s];if(void 0===r||null!=n&&n.equals(t))return!1;for(let i=0;i<r;i++){const s=12*e+12*i,r=this.originalPositionsArray[s],n=this.originalPositionsArray[s+1],o=this.originalPositionsArray[s+2],l=this.originalPositionsArray[s+3],p=this.originalPositionsArray[s+4],y=this.originalPositionsArray[s+5],A=this.originalPositionsArray[s+6],g=this.originalPositionsArray[s+7],f=this.originalPositionsArray[s+8],d=this.originalPositionsArray[s+9],b=this.originalPositionsArray[s+10],m=this.originalPositionsArray[s+11];a.set(r,n,o).applyMatrix4(t),h.set(l,p,y).applyMatrix4(t),u.set(A,g,f).applyMatrix4(t),c.set(d,b,m).applyMatrix4(t),this.positionsArray[s]=a.x,this.positionsArray[s+1]=a.y,this.positionsArray[s+2]=a.z,this.positionsArray[s+3]=h.x,this.positionsArray[s+4]=h.y,this.positionsArray[s+5]=h.z,this.positionsArray[s+6]=u.x,this.positionsArray[s+7]=u.y,this.positionsArray[s+8]=u.z,this.positionsArray[s+9]=c.x,this.positionsArray[s+10]=c.y,this.positionsArray[s+11]=c.z}return this.appliedTransforms[s]=(null!=n?n:new i.Matrix4).copy(t),this.positionsAttribute&&(this.positionsAttribute.needsUpdate=!0),!0}update(t){const{texts:e,...n}=t,a=t.font,h=!1!==t.flipY;a===this.cacheFont&&h===this.cacheFlipY||(this.cache.clear(),this.cacheFont=a,this.cacheFlipY=h,this.signature=null);const u=e.map((t=>({...n,...t}))),c=u.map(p),l=c.join("\n");if(l===this.signature)return;this.signature=l;const y=a.common.scaleW,A=a.common.scaleH,g=u.map(((t,i)=>{var e;const n=c[i],o=null!==(e=this.cache.get(n))&&void 0!==e?e:function(t,i,e,n){const o=s.createLayout(t.text,t),a=o.glyphs.filter((({data:t})=>t.width*t.height>0));return{layout:o,glyphCount:a.length,...r.generateAttributes(a,i,e,n)}}(t,y,A,h);return this.cache.delete(n),this.cache.set(n,o),o}));for(const t of this.cache.keys()){if(this.cache.size<=e.length+256)break;this.cache.delete(t)}this._layouts=g.map((t=>t.layout)),this.instancesOffsetsCache=[],this.instancesLengthsCache=[];let f=0;g.forEach((({glyphCount:t},i)=>{this.instancesLengthsCache[i]=t,this.instancesOffsetsCache[i]=f,f+=t}));const d=f;this.appliedTransforms=[],d!==this.glyphsTotal&&(this.glyphsTotal=d,this.setIndex(o.default([],{clockwise:!0,type:"uint16",count:d})),this.positionsArray=new Float32Array(12*d),this.originalPositionsArray=new Float32Array(12*d),this.centersArray=new Float32Array(8*d),this.uvsArray=new Float32Array(8*d),this.positionsAttribute=new i.BufferAttribute(this.positionsArray,3),this.setAttribute("position",this.positionsAttribute),this.setAttribute("center",new i.BufferAttribute(this.centersArray,2)),this.setAttribute("uv",new i.BufferAttribute(this.uvsArray,2))),g.forEach(((t,i)=>{const s=this.instancesOffsetsCache[i];this.positionsArray.set(t.positions,12*s),this.centersArray.set(t.centers,8*s),this.uvsArray.set(t.uvs,8*s)})),this.originalPositionsArray.set(this.positionsArray);for(const t of["position","center","uv"])this.attributes[t].needsUpdate=!0}dispose(){this.cache.clear(),this.appliedTransforms=[],this.signature=null,super.dispose()}computeBoundingSphere(){null===this.boundingSphere&&(this.boundingSphere=new i.Sphere);const t=this.attributes.position.array,s=this.attributes.position.itemSize;if(!t||!s||t.length<2)return this.boundingSphere.radius=0,void this.boundingSphere.center.set(0,0,0);e.computeSphere(t,this.boundingSphere),isNaN(this.boundingSphere.radius)&&console.error('BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.')}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new i.Box3);const t=this.boundingBox,s=this.attributes.position.array,r=this.attributes.position.itemSize;if(!s||!r||s.length<2)return void t.makeEmpty();return e.computeBox(s,t)}}module.exports=y;
|
|
@@ -40,12 +40,21 @@ export default class MSDFTextGeometry extends BufferGeometry {
|
|
|
40
40
|
_layouts: TextLayout[];
|
|
41
41
|
originalPositionsArray: Float32Array;
|
|
42
42
|
positionsArray: Float32Array;
|
|
43
|
+
centersArray: Float32Array;
|
|
44
|
+
uvsArray: Float32Array;
|
|
43
45
|
positionsAttribute: BufferAttribute | null;
|
|
44
46
|
instancesOffsetsCache: number[];
|
|
45
47
|
instancesLengthsCache: number[];
|
|
48
|
+
private cache;
|
|
49
|
+
private cacheFont;
|
|
50
|
+
private cacheFlipY;
|
|
51
|
+
private signature;
|
|
52
|
+
private glyphsTotal;
|
|
53
|
+
private appliedTransforms;
|
|
46
54
|
constructor(options: IOptions);
|
|
47
|
-
setTransform(transform: Matrix4, instance?: number):
|
|
55
|
+
setTransform(transform: Matrix4, instance?: number): boolean;
|
|
48
56
|
update(options: IOptions): void;
|
|
57
|
+
dispose(): void;
|
|
49
58
|
computeBoundingSphere(): void;
|
|
50
59
|
computeBoundingBox(): Box3 | undefined;
|
|
51
60
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import createIndices from 'quad-indices';
|
|
2
|
-
import { BufferGeometry, BufferAttribute, Sphere, Box3, Vector3 } from 'three';
|
|
2
|
+
import { BufferGeometry, Matrix4, BufferAttribute, Sphere, Box3, Vector3 } from 'three';
|
|
3
3
|
import { createLayout } from './TextLayout.js';
|
|
4
4
|
import { computeSphere, computeBox } from './utils.js';
|
|
5
5
|
import { generateAttributes } from './vertices.js';
|
|
@@ -10,20 +10,75 @@ const pointA = new Vector3();
|
|
|
10
10
|
const pointB = new Vector3();
|
|
11
11
|
const pointC = new Vector3();
|
|
12
12
|
const pointD = new Vector3();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The options that decide how one instance looks.
|
|
16
|
+
*
|
|
17
|
+
* Instances with equal values share a layout and its vertices, so the cache is keyed on them. An
|
|
18
|
+
* option that changes the layout but is missing here makes the cache return a stale layout.
|
|
19
|
+
* `alignY` and `yShift` do not move glyphs, but consumers read them from `_layouts[i]._options`.
|
|
20
|
+
*/
|
|
21
|
+
const LAYOUT_KEYS = ['text', 'width', 'lineHeight', 'letterSpacing', 'alignX', 'alignY', 'yShift', 'tabSize'];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* How many unused instances the cache keeps.
|
|
25
|
+
*
|
|
26
|
+
* A drag removes and adds the same labels many times, so an unused instance is likely to come back.
|
|
27
|
+
*/
|
|
28
|
+
const CACHE_HEADROOM = 256;
|
|
29
|
+
function signatureOf(options) {
|
|
30
|
+
return JSON.stringify(LAYOUT_KEYS.map(key => options[key]));
|
|
31
|
+
}
|
|
32
|
+
function layOut(options, texWidth, texHeight, flipY) {
|
|
33
|
+
const layout = createLayout(options.text, options);
|
|
34
|
+
// A glyph with no area draws nothing
|
|
35
|
+
const glyphs = layout.glyphs.filter(({
|
|
36
|
+
data
|
|
37
|
+
}) => data.width * data.height > 0);
|
|
38
|
+
return {
|
|
39
|
+
layout,
|
|
40
|
+
glyphCount: glyphs.length,
|
|
41
|
+
...generateAttributes(glyphs, texWidth, texHeight, flipY)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
13
44
|
class MSDFTextGeometry extends BufferGeometry {
|
|
14
45
|
originalPositionsArray = new Float32Array();
|
|
15
46
|
positionsArray = new Float32Array();
|
|
47
|
+
centersArray = new Float32Array();
|
|
48
|
+
uvsArray = new Float32Array();
|
|
16
49
|
positionsAttribute = null;
|
|
17
50
|
instancesOffsetsCache = [];
|
|
18
51
|
instancesLengthsCache = [];
|
|
52
|
+
|
|
53
|
+
/** Laid-out instances by signature, in least-recently-used order. */
|
|
54
|
+
cache = new Map();
|
|
55
|
+
cacheFont = null;
|
|
56
|
+
cacheFlipY = true;
|
|
57
|
+
/** The signatures of the last update. `null` makes the next update run. */
|
|
58
|
+
signature = null;
|
|
59
|
+
/** `-1` makes the first update build the index and the attributes, also for zero glyphs. */
|
|
60
|
+
glyphsTotal = -1;
|
|
61
|
+
/** The last matrix written per instance. */
|
|
62
|
+
appliedTransforms = [];
|
|
19
63
|
constructor(options) {
|
|
20
64
|
super();
|
|
21
65
|
this._layouts = [];
|
|
22
66
|
this.update(options);
|
|
23
67
|
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Write the glyph positions of one instance. Returns whether anything was written.
|
|
71
|
+
*
|
|
72
|
+
* Consumers call this for every instance on every frame, and most instances do not move. A write
|
|
73
|
+
* marks the whole shared buffer for upload to the GPU, so an unchanged matrix is skipped.
|
|
74
|
+
*/
|
|
24
75
|
setTransform(transform, instance = 0) {
|
|
25
76
|
const instanceOffset = this.instancesOffsetsCache[instance];
|
|
26
77
|
const instanceLength = this.instancesLengthsCache[instance];
|
|
78
|
+
const applied = this.appliedTransforms[instance];
|
|
79
|
+
if (instanceLength === undefined || applied != null && applied.equals(transform)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
27
82
|
for (let i = 0; i < instanceLength; i++) {
|
|
28
83
|
const instanceGlyphOffset = instanceOffset * 12 + i * 12;
|
|
29
84
|
const originalXA = this.originalPositionsArray[instanceGlyphOffset];
|
|
@@ -55,75 +110,114 @@ class MSDFTextGeometry extends BufferGeometry {
|
|
|
55
110
|
this.positionsArray[instanceGlyphOffset + 10] = pointD.y;
|
|
56
111
|
this.positionsArray[instanceGlyphOffset + 11] = pointD.z;
|
|
57
112
|
}
|
|
113
|
+
|
|
114
|
+
// Callers reuse one matrix for all instances, so keep a copy
|
|
115
|
+
this.appliedTransforms[instance] = (applied !== null && applied !== void 0 ? applied : new Matrix4()).copy(transform);
|
|
58
116
|
if (this.positionsAttribute) {
|
|
59
117
|
this.positionsAttribute.needsUpdate = true;
|
|
60
118
|
}
|
|
119
|
+
return true;
|
|
61
120
|
}
|
|
62
121
|
update(options) {
|
|
63
122
|
const {
|
|
64
123
|
texts,
|
|
65
124
|
...optionsWithoutTexts
|
|
66
125
|
} = options;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}));
|
|
126
|
+
|
|
127
|
+
// the desired BMFont data
|
|
128
|
+
const font = options.font;
|
|
71
129
|
|
|
72
130
|
// get vec2 texcoords
|
|
73
131
|
const flipY = options.flipY !== false;
|
|
74
132
|
|
|
75
|
-
// the
|
|
76
|
-
|
|
133
|
+
// A cached layout belongs to the font and the atlas orientation that produced it
|
|
134
|
+
if (font !== this.cacheFont || flipY !== this.cacheFlipY) {
|
|
135
|
+
this.cache.clear();
|
|
136
|
+
this.cacheFont = font;
|
|
137
|
+
this.cacheFlipY = flipY;
|
|
138
|
+
this.signature = null;
|
|
139
|
+
}
|
|
140
|
+
const instancesOptions = texts.map(txt => ({
|
|
141
|
+
...optionsWithoutTexts,
|
|
142
|
+
...txt
|
|
143
|
+
}));
|
|
144
|
+
const signatures = instancesOptions.map(signatureOf);
|
|
145
|
+
|
|
146
|
+
// Consumers call update on every insert and remove, far more often than the content changes
|
|
147
|
+
const signature = signatures.join('\n');
|
|
148
|
+
if (signature === this.signature) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.signature = signature;
|
|
77
152
|
|
|
78
153
|
// determine texture size from font file
|
|
79
154
|
const texWidth = font.common.scaleW;
|
|
80
155
|
const texHeight = font.common.scaleH;
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
156
|
+
const instances = instancesOptions.map((instanceOptions, i) => {
|
|
157
|
+
var _this$cache$get;
|
|
158
|
+
const key = signatures[i];
|
|
159
|
+
const instance = (_this$cache$get = this.cache.get(key)) !== null && _this$cache$get !== void 0 ? _this$cache$get : layOut(instanceOptions, texWidth, texHeight, flipY);
|
|
160
|
+
// Re-insert, so the instances in use move to the end of the map
|
|
161
|
+
this.cache.delete(key);
|
|
162
|
+
this.cache.set(key, instance);
|
|
163
|
+
return instance;
|
|
164
|
+
});
|
|
165
|
+
for (const key of this.cache.keys()) {
|
|
166
|
+
if (this.cache.size <= texts.length + CACHE_HEADROOM) break;
|
|
167
|
+
this.cache.delete(key);
|
|
168
|
+
}
|
|
169
|
+
this._layouts = instances.map(instance => instance.layout);
|
|
85
170
|
|
|
86
171
|
// Keep a cache of each text instance offset and length for attributes
|
|
87
172
|
this.instancesOffsetsCache = [];
|
|
88
173
|
this.instancesLengthsCache = [];
|
|
89
174
|
let offsetSoFar = 0;
|
|
90
|
-
|
|
91
|
-
|
|
175
|
+
instances.forEach(({
|
|
176
|
+
glyphCount
|
|
177
|
+
}, i) => {
|
|
178
|
+
this.instancesLengthsCache[i] = glyphCount;
|
|
92
179
|
this.instancesOffsetsCache[i] = offsetSoFar;
|
|
93
|
-
offsetSoFar +=
|
|
180
|
+
offsetSoFar += glyphCount;
|
|
94
181
|
});
|
|
95
182
|
const totalGlyphsLength = offsetSoFar;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
183
|
+
|
|
184
|
+
// Instances move inside the shared buffers, so no applied matrix still holds
|
|
185
|
+
this.appliedTransforms = [];
|
|
186
|
+
|
|
187
|
+
// The index and the buffer sizes follow from the glyph count. While it stays the same, refill the
|
|
188
|
+
// buffers in place and keep the attributes and the GPU buffers behind them.
|
|
189
|
+
if (totalGlyphsLength !== this.glyphsTotal) {
|
|
190
|
+
this.glyphsTotal = totalGlyphsLength;
|
|
191
|
+
this.setIndex(createIndices([], {
|
|
192
|
+
clockwise: true,
|
|
193
|
+
type: 'uint16',
|
|
194
|
+
count: totalGlyphsLength
|
|
195
|
+
}));
|
|
196
|
+
this.positionsArray = new Float32Array(totalGlyphsLength * 12);
|
|
197
|
+
this.originalPositionsArray = new Float32Array(totalGlyphsLength * 12);
|
|
198
|
+
this.centersArray = new Float32Array(totalGlyphsLength * 8);
|
|
199
|
+
this.uvsArray = new Float32Array(totalGlyphsLength * 8);
|
|
200
|
+
this.positionsAttribute = new BufferAttribute(this.positionsArray, 3);
|
|
201
|
+
this.setAttribute('position', this.positionsAttribute);
|
|
202
|
+
this.setAttribute('center', new BufferAttribute(this.centersArray, 2));
|
|
203
|
+
this.setAttribute('uv', new BufferAttribute(this.uvsArray, 2));
|
|
204
|
+
}
|
|
205
|
+
instances.forEach((instance, i) => {
|
|
206
|
+
const offset = this.instancesOffsetsCache[i];
|
|
207
|
+
this.positionsArray.set(instance.positions, offset * 12);
|
|
208
|
+
this.centersArray.set(instance.centers, offset * 8);
|
|
209
|
+
this.uvsArray.set(instance.uvs, offset * 8);
|
|
119
210
|
});
|
|
120
|
-
this.positionsArray
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
this.
|
|
211
|
+
this.originalPositionsArray.set(this.positionsArray);
|
|
212
|
+
for (const name of ['position', 'center', 'uv']) {
|
|
213
|
+
this.attributes[name].needsUpdate = true;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
dispose() {
|
|
217
|
+
this.cache.clear();
|
|
218
|
+
this.appliedTransforms = [];
|
|
219
|
+
this.signature = null;
|
|
220
|
+
super.dispose();
|
|
127
221
|
}
|
|
128
222
|
computeBoundingSphere() {
|
|
129
223
|
if (this.boundingSphere === null) this.boundingSphere = new Sphere();
|