-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
1 lines (1 loc) · 19.7 KB
/
index.js
File metadata and controls
1 lines (1 loc) · 19.7 KB
1
var Ef=Object.create;var{getPrototypeOf:cf,defineProperty:o,getOwnPropertyNames:jf}=Object;var gf=Object.prototype.hasOwnProperty;var Qf=(f,k,A)=>{A=f!=null?Ef(cf(f)):{};let _=k||!f||!f.__esModule?o(A,"default",{value:f,enumerable:!0}):A;for(let R of jf(f))if(!gf.call(_,R))o(_,R,{get:()=>f[R],enumerable:!0});return _};var If=(f,k)=>{for(var A in k)o(f,A,{get:k[A],enumerable:!0,configurable:!0,set:(_)=>k[A]=()=>_})};var Sf=(f,k)=>()=>(f&&(k=f(f=0)),k);var $f=((f)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(f,{get:(k,A)=>(typeof require<"u"?require:k)[A]}):f)(function(f){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+f+'" is not supported')});var Bf={};If(Bf,{sep:()=>Of,resolve:()=>S,relative:()=>Zf,posix:()=>Nf,parse:()=>Uf,normalize:()=>r,join:()=>Yf,isAbsolute:()=>Wf,format:()=>Df,extname:()=>Gf,dirname:()=>Xf,delimiter:()=>Pf,default:()=>zf,basename:()=>Cf,_makeLong:()=>Vf});function M(f){if(typeof f!=="string")throw TypeError("Path must be a string. Received "+JSON.stringify(f))}function Jf(f,k){var A="",_=0,R=-1,K=0,F;for(var q=0;q<=f.length;++q){if(q<f.length)F=f.charCodeAt(q);else if(F===47)break;else F=47;if(F===47){if(R===q-1||K===1);else if(R!==q-1&&K===2){if(A.length<2||_!==2||A.charCodeAt(A.length-1)!==46||A.charCodeAt(A.length-2)!==46){if(A.length>2){var H=A.lastIndexOf("/");if(H!==A.length-1){if(H===-1)A="",_=0;else A=A.slice(0,H),_=A.length-1-A.lastIndexOf("/");R=q,K=0;continue}}else if(A.length===2||A.length===1){A="",_=0,R=q,K=0;continue}}if(k){if(A.length>0)A+="/..";else A="..";_=2}}else{if(A.length>0)A+="/"+f.slice(R+1,q);else A=f.slice(R+1,q);_=q-R-1}R=q,K=0}else if(F===46&&K!==-1)++K;else K=-1}return A}function bf(f,k){var A=k.dir||k.root,_=k.base||(k.name||"")+(k.ext||"");if(!A)return _;if(A===k.root)return A+_;return A+f+_}function S(){var f="",k=!1,A;for(var _=arguments.length-1;_>=-1&&!k;_--){var R;if(_>=0)R=arguments[_];else{if(A===void 0)A=process.cwd();R=A}if(M(R),R.length===0)continue;f=R+"/"+f,k=R.charCodeAt(0)===47}if(f=Jf(f,!k),k)if(f.length>0)return"/"+f;else return"/";else if(f.length>0)return f;else return"."}function r(f){if(M(f),f.length===0)return".";var k=f.charCodeAt(0)===47,A=f.charCodeAt(f.length-1)===47;if(f=Jf(f,!k),f.length===0&&!k)f=".";if(f.length>0&&A)f+="/";if(k)return"/"+f;return f}function Wf(f){return M(f),f.length>0&&f.charCodeAt(0)===47}function Yf(){if(arguments.length===0)return".";var f;for(var k=0;k<arguments.length;++k){var A=arguments[k];if(M(A),A.length>0)if(f===void 0)f=A;else f+="/"+A}if(f===void 0)return".";return r(f)}function Zf(f,k){if(M(f),M(k),f===k)return"";if(f=S(f),k=S(k),f===k)return"";var A=1;for(;A<f.length;++A)if(f.charCodeAt(A)!==47)break;var _=f.length,R=_-A,K=1;for(;K<k.length;++K)if(k.charCodeAt(K)!==47)break;var F=k.length,q=F-K,H=R<q?R:q,W=-1,$=0;for(;$<=H;++$){if($===H){if(q>H){if(k.charCodeAt(K+$)===47)return k.slice(K+$+1);else if($===0)return k.slice(K+$)}else if(R>H){if(f.charCodeAt(A+$)===47)W=$;else if($===0)W=0}break}var V=f.charCodeAt(A+$),J=k.charCodeAt(K+$);if(V!==J)break;else if(V===47)W=$}var Q="";for($=A+W+1;$<=_;++$)if($===_||f.charCodeAt($)===47)if(Q.length===0)Q+="..";else Q+="/..";if(Q.length>0)return Q+k.slice(K+W);else{if(K+=W,k.charCodeAt(K)===47)++K;return k.slice(K)}}function Vf(f){return f}function Xf(f){if(M(f),f.length===0)return".";var k=f.charCodeAt(0),A=k===47,_=-1,R=!0;for(var K=f.length-1;K>=1;--K)if(k=f.charCodeAt(K),k===47){if(!R){_=K;break}}else R=!1;if(_===-1)return A?"/":".";if(A&&_===1)return"//";return f.slice(0,_)}function Cf(f,k){if(k!==void 0&&typeof k!=="string")throw TypeError('"ext" argument must be a string');M(f);var A=0,_=-1,R=!0,K;if(k!==void 0&&k.length>0&&k.length<=f.length){if(k.length===f.length&&k===f)return"";var F=k.length-1,q=-1;for(K=f.length-1;K>=0;--K){var H=f.charCodeAt(K);if(H===47){if(!R){A=K+1;break}}else{if(q===-1)R=!1,q=K+1;if(F>=0)if(H===k.charCodeAt(F)){if(--F===-1)_=K}else F=-1,_=q}}if(A===_)_=q;else if(_===-1)_=f.length;return f.slice(A,_)}else{for(K=f.length-1;K>=0;--K)if(f.charCodeAt(K)===47){if(!R){A=K+1;break}}else if(_===-1)R=!1,_=K+1;if(_===-1)return"";return f.slice(A,_)}}function Gf(f){M(f);var k=-1,A=0,_=-1,R=!0,K=0;for(var F=f.length-1;F>=0;--F){var q=f.charCodeAt(F);if(q===47){if(!R){A=F+1;break}continue}if(_===-1)R=!1,_=F+1;if(q===46){if(k===-1)k=F;else if(K!==1)K=1}else if(k!==-1)K=-1}if(k===-1||_===-1||K===0||K===1&&k===_-1&&k===A+1)return"";return f.slice(k,_)}function Df(f){if(f===null||typeof f!=="object")throw TypeError('The "pathObject" argument must be of type Object. Received type '+typeof f);return bf("/",f)}function Uf(f){M(f);var k={root:"",dir:"",base:"",ext:"",name:""};if(f.length===0)return k;var A=f.charCodeAt(0),_=A===47,R;if(_)k.root="/",R=1;else R=0;var K=-1,F=0,q=-1,H=!0,W=f.length-1,$=0;for(;W>=R;--W){if(A=f.charCodeAt(W),A===47){if(!H){F=W+1;break}continue}if(q===-1)H=!1,q=W+1;if(A===46){if(K===-1)K=W;else if($!==1)$=1}else if(K!==-1)$=-1}if(K===-1||q===-1||$===0||$===1&&K===q-1&&K===F+1){if(q!==-1)if(F===0&&_)k.base=k.name=f.slice(1,q);else k.base=k.name=f.slice(F,q)}else{if(F===0&&_)k.name=f.slice(1,K),k.base=f.slice(1,q);else k.name=f.slice(F,K),k.base=f.slice(F,q);k.ext=f.slice(K,q)}if(F>0)k.dir=f.slice(0,F-1);else if(_)k.dir="/";return k}var Of="/",Pf=":",Nf,zf;var hf=Sf(()=>{Nf=((f)=>(f.posix=f,f))({resolve:S,normalize:r,isAbsolute:Wf,join:Yf,relative:Zf,_makeLong:Vf,dirname:Xf,basename:Cf,extname:Gf,format:Df,parse:Uf,sep:Of,delimiter:Pf,win32:null,posix:null}),zf=Nf});function x(f){return new Float32Array(f)}function yf(f){let k=[];for(let A=1;A+1<f.length;A++)k.push(f[0],f[A],f[A+1]);return k}function n(f,k){let A=parseInt(f,10);if(isNaN(A))throw Error(`Malformed OBJ index: '${f}'`);if(A>0)return A-1;return k+A}function lf(f){let k={x:1/0,y:1/0,z:1/0},A={x:-1/0,y:-1/0,z:-1/0};for(let _=0;_<f.length;_+=3){let R=f[_],K=f[_+1],F=f[_+2];if(R<k.x)k.x=R;if(K<k.y)k.y=K;if(F<k.z)k.z=F;if(R>A.x)A.x=R;if(K>A.y)A.y=K;if(F>A.z)A.z=F}return{min:k,max:A}}class s{parse(f,k){let A=[],_=[],R=[],K=[],F={name:"default",materialName:null,faceVertexStrs:[]};K.push(F);let q={};if(k)for(let[$,V]of Object.entries(k)){let J=this.parseMTL(V);Object.assign(q,J)}let H=f.split(/\r?\n/);for(let $ of H){let V=$.trim();if(!V||V.startsWith("#"))continue;let J=V.split(/\s+/);switch(J[0]){case"v":{let[C,Y,X]=J.slice(1,4).map(Number);if([C,Y,X].some((U)=>isNaN(U)))throw Error(`Malformed vertex position: ${J.join(" ")}`);A.push(C,Y,X);break}case"vt":{let[C,Y]=[parseFloat(J[1]),parseFloat(J[2]??"0")];if(isNaN(C)||isNaN(Y))throw Error(`Malformed texture coordinate: ${J.join(" ")}`);_.push(C,Y);break}case"vn":{let[C,Y,X]=J.slice(1,4).map(Number);if([C,Y,X].some((U)=>isNaN(U)))throw Error(`Malformed normal: ${J.join(" ")}`);R.push(C,Y,X);break}case"f":{let C=J.slice(1);if(C.length<3)throw Error(`Face with less than 3 vertices: ${J.join(" ")}`);F.faceVertexStrs.push(C);break}case"o":case"g":{F={name:J.slice(1).join(" ")||"unnamed",materialName:null,faceVertexStrs:[]},K.push(F);break}case"usemtl":{let C=J[1]??null;F.materialName=C;break}case"mtllib":break;case"s":break;default:break}}let W=[];for(let $ of K){let X=function(Z,D,G){let O=`${Z??""}_${D??""}_${G??""}`,P=V.get(O);if(P!==void 0)return P;P=J.length/3,V.set(O,P);let h=Z*3,[w,u,L]=[A[h],A[h+1],A[h+2]];if(J.push(w,u,L),D!==void 0&&!isNaN(D)){let B=D*2,[c,j]=[_[B]??0,_[B+1]??0];C.push(c,j)}else C.push(0,0);if(G!==void 0&&!isNaN(G)){let B=G*3,[c,j,d]=[R[B]??0,R[B+1]??0,R[B+2]??0];Q.push(c,j,d)}else Q.push(0,0,0);return P};if($.faceVertexStrs.length===0)continue;let V=new Map,J=[],Q=[],C=[],Y=[];for(let Z of $.faceVertexStrs){let D=[];for(let O of Z){let P=O.split("/"),h=n(P[0],A.length/3),w=P[1]?n(P[1],_.length/2):void 0,u=P[2]?n(P[2],R.length/3):void 0,L=X(h,w,u);D.push(L)}let G=yf(D);Y.push(...G)}let U=!0;for(let Z=0;Z<Q.length;Z++)if(Q[Z]!==0){U=!1;break}if(U){for(let Z=0;Z<Q.length;Z++)Q[Z]=0;for(let Z=0;Z<Y.length;Z+=3){let D=Y[Z]*3,G=Y[Z+1]*3,O=Y[Z+2]*3,[P,h,w]=[J[D],J[D+1],J[D+2]],[u,L,B]=[J[G],J[G+1],J[G+2]],[c,j,d]=[J[O],J[O+1],J[O+2]],[_f,Ff,Kf]=[u-P,L-h,B-w],[Rf,qf,Hf]=[c-P,j-h,d-w],i=Ff*Hf-Kf*qf,m=Kf*Rf-_f*Hf,p=_f*qf-Ff*Rf;Q[D]+=i,Q[D+1]+=m,Q[D+2]+=p,Q[G]+=i,Q[G+1]+=m,Q[G+2]+=p,Q[O]+=i,Q[O+1]+=m,Q[O+2]+=p}for(let Z=0;Z<Q.length;Z+=3){let[D,G,O]=[Q[Z],Q[Z+1],Q[Z+2]],P=Math.hypot(D,G,O)||1;Q[Z]=D/P,Q[Z+1]=G/P,Q[Z+2]=O/P}}let N={name:$.name,materialName:$.materialName??null,positions:x(J),normals:x(Q),boundingBox:lf(x(J)),uvs:C.length>0?new Float32Array(C):null,indices:new Uint32Array(Y)};W.push(N)}return{meshes:W,materials:q}}parseMTL(f){let k=f.split(/\r?\n/),A={},_=null;for(let R of k){let K=R.trim();if(!K||K.startsWith("#"))continue;let F=K.split(/\s+/);switch(F[0]){case"newmtl":{let H=F[1]??"unnamed";_={name:H},A[H]=_;break}case"Kd":{if(!_)break;let H=[parseFloat(F[1]),parseFloat(F[2]),parseFloat(F[3])];if(H.some((W)=>isNaN(W)))throw Error(`Malformed Kd: ${F.join(" ")}`);_.kd=H;break}case"Ks":{if(!_)break;let H=[parseFloat(F[1]),parseFloat(F[2]),parseFloat(F[3])];if(H.some((W)=>isNaN(W)))throw Error(`Malformed Ks: ${F.join(" ")}`);_.ks=H;break}case"Ns":{if(!_)break;let H=parseFloat(F[1]);if(isNaN(H))throw Error(`Malformed Ns: ${F.join(" ")}`);_.ns=H;break}case"map_Kd":{if(!_)break;_.mapKd=F.slice(1).join(" ");break}default:break}}return A}async loadFromText(f,k){let A={},_=[],R=f.split(/\r?\n/);for(let K of R){let F=K.trim();if(!F)continue;let q=F.split(/\s+/);if(q[0]==="mtllib"&&q[1])_.push(q[1])}if(_.length&&k?.mtlResolver)for(let K of _)try{let F=await k.mtlResolver(K);if(F)A[K]=F}catch(F){}else if(_.length&&k?.objPath){let K=await import("fs/promises"),F=await Promise.resolve().then(() => (hf(),Bf)),q=F.dirname(k.objPath);for(let H of _)try{let W=F.join(q,H),$=await K.readFile(W,"utf8");A[H]=$}catch(W){}}return this.parse(f,Object.keys(A).length?A:void 0)}async loadFromUrl(f,k){let A=await fetch(f);if(!A.ok)throw Error(`Failed to fetch OBJ: ${A.status}`);let _=await A.text();return this.loadFromText(_,k)}async loadFromFile(f,k){let _=await(await import("fs/promises")).readFile(f,"utf8");return this.loadFromText(_,{...k,objPath:f})}}function t(f,k){let A=Array(16);for(let _=0;_<4;_++)for(let R=0;R<4;R++){let K=0;for(let F=0;F<4;F++)K+=f[_*4+F]*k[F*4+R];A[_*4+R]=K}return A}function g(f,k){return{x:f[0]*k.x+f[1]*k.y+f[2]*k.z+f[3]*k.w,y:f[4]*k.x+f[5]*k.y+f[6]*k.z+f[7]*k.w,z:f[8]*k.x+f[9]*k.y+f[10]*k.z+f[11]*k.w,w:f[12]*k.x+f[13]*k.y+f[14]*k.z+f[15]*k.w}}function Mf(f,k,A,_){let R=1/Math.tan(f/2),K=1/(A-_);return[R/k,0,0,0,0,R,0,0,0,0,(_+A)*K,2*_*A*K,0,0,-1,0]}function Tf(f,k,A){let _=f.x-k.x,R=f.y-k.y,K=f.z-k.z,F=Math.hypot(_,R,K);if(F===0)F=1;let q=_/F,H=R/F,W=K/F,$=A.y*W-A.z*H,V=A.z*q-A.x*W,J=A.x*H-A.y*q,Q=Math.hypot($,V,J);if(Q===0)Q=1;let C=$/Q,Y=V/Q,X=J/Q,U=H*X-W*Y,N=W*C-q*X,Z=q*Y-H*C;return[C,Y,X,-(C*f.x+Y*f.y+X*f.z),U,N,Z,-(U*f.x+N*f.y+Z*f.z),q,H,W,-(q*f.x+H*f.y+W*f.z),0,0,0,1]}function wf(f){let k=Math.cos(f),A=Math.sin(f);return[k,0,A,0,0,1,0,0,-A,0,k,0,0,0,0,1]}function a(f,k,A,_){let R={x:f.x,y:f.y,z:f.z,w:1},K=g(k,R);if(K.w===0)return null;let F={x:K.x/K.w,y:K.y/K.w,z:K.z/K.w},q=(F.x*0.5+0.5)*A,H=(1-(F.y*0.5+0.5))*_,W=F.z*0.5+0.5;return{screenX:q,screenY:H,screenZ:W,ndc:F,clipW:K.w}}function uf(f,k,A,_,R,K){let F=a(f,_,R,K),q=a(k,_,R,K),H=a(A,_,R,K);if(!F||!q||!H)return null;return[{x:F.screenX,y:F.screenY,z:F.screenZ,recipW:1/F.clipW},{x:q.screenX,y:q.screenY,z:q.screenZ,recipW:1/q.clipW},{x:H.screenX,y:H.screenY,z:H.screenZ,recipW:1/H.clipW}]}function Lf(f,k,A,_,R){let K=(F)=>F.x<0||F.x>=_||F.y<0||F.y>=R;if(K(f)&&K(k)&&K(A))return!0;return!1}function z(f,k,A,_,R){let K=_&&_.length>k+2?{x:_[k],y:_[k+1],z:_[k+2]}:void 0,F=R&&R.length>A+1?[R[A],R[A+1]]:void 0;return{x:f.x,y:f.y,z:f.z,recipW:f.recipW,color:void 0,normal:K,uv:F}}var E=(f,k)=>({x:f.x-k.x,y:f.y-k.y,z:f.z-k.z}),y=(f,k)=>({x:f.y*k.z-f.z*k.y,y:f.z*k.x-f.x*k.z,z:f.x*k.y-f.y*k.x}),ef=(f)=>Math.hypot(f.x,f.y,f.z)||1,T=(f)=>{let k=ef(f);return{x:f.x/k,y:f.y/k,z:f.z/k}},b=(f,k)=>f.x*k.x+f.y*k.y+f.z*k.z,v=(f,k)=>({x:f.x+k.x,y:f.y+k.y,z:f.z+k.z}),I=(f,k)=>({x:f.x*k,y:f.y*k,z:f.z*k});function l(f,k,A,_){let K=0,F=0;if(_){let W=T(_.direction),$={x:-W.x,y:-W.y,z:-W.z},V=T(k);K=Math.max(0,b(V,$))*_.intensity;let J=T({x:A.x+$.x,y:A.y+$.y,z:A.z+$.z}),Q=Math.max(0,b(V,J));F=Math.pow(Q,16)*_.intensity}let q={x:200,y:120,z:60},H=0.85;return{x:Math.max(0,Math.min(255,q.x*(0.15+H*K+F))),y:Math.max(0,Math.min(255,q.y*(0.15+H*K+F))),z:Math.max(0,Math.min(255,q.z*(0.15+H*K+F)))}}function e(f,k=1){return{x:Math.round(f.x/k)*k,y:Math.round(f.y/k)*k,z:f.z,recipW:f.recipW,color:void 0,normal:f.normal,uv:f.uv}}class ff{position;up;speed;yaw;pitch;constructor(f,k,A=1,_=0,R=0){this.position=f,this.up=k,this.speed=A,this.yaw=_,this.pitch=R,this.initKeyboardControls()}initKeyboardControls(){window.addEventListener("keydown",(f)=>{switch(f.key){case"w":this.moveForward();break;case"s":this.moveBackward();break;case"a":this.moveLeft();break;case"d":this.moveRight();break;case"ArrowRight":this.rotateY(0.1);break;case"ArrowLeft":this.rotateY(-0.1);break}})}getForwardVector(){let f=Math.cos(this.pitch);return{x:Math.cos(this.yaw)*f,y:Math.sin(this.pitch),z:Math.sin(this.yaw)*f}}getRightVector(){let f=this.getForwardVector();return T(y(f,this.up))}moveForward(){let f=this.getForwardVector();this.position=v(this.position,I(f,this.speed))}moveBackward(){let f=this.getForwardVector();this.position=E(this.position,I(f,this.speed))}moveLeft(){let f=this.getRightVector();this.position=E(this.position,I(f,this.speed))}moveRight(){let f=this.getRightVector();this.position=v(this.position,I(f,this.speed))}rotateY(f){this.yaw+=f}}class kf{direction;color;intensity;constructor(f,k,A){this.direction=f,this.color=k,this.intensity=A}}class Af{canvas;ctx;width;height;running=!1;timescale=0.001;littleEndian;imageData;buffer;buf8;data32;zBuffer;objModels=[];mainCamera=null;mainDirectionalLight=null;lastFpsUpdate=0;frameCount=0;fps=0;options;projMatrix;rasterWorker;constructor(f,k={}){this.options=k,this.canvas=document.getElementById(f),this.ctx=this.canvas.getContext("2d"),this.width=this.canvas.width,this.height=this.canvas.height,this.imageData=this.ctx?.getImageData(0,0,this.width,this.height);let A=this.imageData.data.length;this.buffer=new ArrayBuffer(A),this.buf8=new Uint8ClampedArray(this.buffer),this.data32=new Uint32Array(this.buffer);let _=new Uint32Array([168496141]),R=new Uint8Array(_.buffer);this.littleEndian=R[0]===13,this.zBuffer=new Float32Array(this.width*this.height),this.clearZ();let K=this.width/this.height;this.projMatrix=Mf(Math.PI/3,K,0.1,100),this.rasterWorker=new Worker("./src/RasterWorker.js"),this.rasterWorker.onmessage=(F)=>{let{buf8:q}=F.data;this.buf8.set(q),this.present()}}drawLine3DEFLA(f,k,A,_,R,K,F,q,H,W=255){let $=Math.abs(_-f),V=Math.abs(R-k),J=Math.abs(K-A),Q=f<_?1:-1,C=k<R?1:-1,Y=A<K?1:-1,X=Math.max($,V,J),U=0,N=0;if(X===$)U=V,N=J;else if(X===V)U=$,N=J;else U=$,N=V;let Z=U===0?0:(U<<16)/X,D=N===0?0:(N<<16)/X,G=0,O=0;for(let P=0;P<=X;P++){if(this.depthTest(f,k,A))this.setPixel(f,k,F,q,H,W);if(X===$)f+=Q,G+=Z,O+=D,k+=(G>>16)*C,A+=(O>>16)*Y,G&=65535,O&=65535;else if(X===V)k+=C,G+=Z,O+=D,f+=(G>>16)*Q,A+=(O>>16)*Y,G&=65535,O&=65535;else A+=Y,G+=Z,O+=D,f+=(G>>16)*Q,k+=(O>>16)*C,G&=65535,O&=65535}}drawTriangleScanline(f,k,A,_={x:200,y:120,z:60}){let[R,K,F]=[f,k,A].sort((Y,X)=>Y.y-X.y),q=Math.max(0,Math.ceil(Math.min(R.y,K.y,F.y))),H=Math.min(this.height-1,Math.floor(Math.max(R.y,K.y,F.y))),W=J(R,F),$=J(R,K),V=J(K,F);for(let Y=q;Y<=H;Y++){let X=Q(W,Y),U=Y<K.y?Q($,Y):Q(V,Y);if(X>U)[X,U]=[U,X];let N=Math.max(0,Math.ceil(X)),Z=Math.min(this.width-1,Math.floor(U));for(let D=N;D<=Z;D++){let G=U===X?0:(D-X)/(U-X),O=C(W,$,V,D,Y,G);if(this.depthTest(D,Y,O))this.setPixel(D,Y,_.x,_.y,_.z)}}function J(Y,X){let U=X.y-Y.y,N=X.x-Y.x,Z=X.z-Y.z;return{vStart:Y,vEnd:X,dx:N,dy:U,dz:Z}}function Q(Y,X){let{vStart:U,vEnd:N,dx:Z,dy:D}=Y;if(D===0)return U.x;return U.x+Z*((X-U.y)/D)}function C(Y,X,U,N,Z,D){return Y.vStart.z+(Y.vEnd.z-Y.vStart.z)*D}}start(){if(this.running)return;this.running=!0,this.lastFpsUpdate=performance.now(),this.frameCount=0;let f=(k)=>{this.clear(20,20,30),this.clearZ(),this.renderPixel(k*this.timescale),this.present(),this.frameCount++;let A=performance.now();if(A-this.lastFpsUpdate>=1000)this.fps=this.frameCount,this.frameCount=0,this.lastFpsUpdate=A;if(this.ctx.fillStyle="white",this.ctx.font="16px monospace",this.ctx.fillText(`FPS: ${this.fps}`,10,20),this.running)requestAnimationFrame(f)};requestAnimationFrame(f)}stop(){this.running=!1}benchmark(f=300){this.running=!1;let k=performance.now();for(let R=0;R<f;R++)this.clear(20,20,30),this.clearZ(),this.renderPixel(R*this.timescale),this.present();let A=performance.now(),_=f/((A-k)/1000);this.ctx.fillStyle="white",this.ctx.font="16px monospace",this.ctx.fillText(`FPS: ${_.toFixed(2)}`,10,20)}renderPixel(f){let k=wf(f),A=this.mainCamera.getForwardVector(),_={x:this.mainCamera.position.x+A.x,y:this.mainCamera.position.y+A.y,z:this.mainCamera.position.z+A.z},R=Tf(this.mainCamera.position,_,this.mainCamera.up),K=t(R,k),F=t(this.projMatrix,K);for(let q of this.objModels)for(let H of q.meshes)this.renderMesh(H,F,k);if(this.imageData)this.imageData.data.set(this.buf8),this.ctx.putImageData(this.imageData,0,0)}renderMesh(f,k,A){let{positions:_,normals:R,uvs:K,indices:F}=f,q=[];for(let H=0;H<F.length;H+=3){let W=F[H]*3,$=F[H+1]*3,V=F[H+2]*3,J={x:_[W],y:_[W+1],z:_[W+2]},Q={x:_[$],y:_[$+1],z:_[$+2]},C={x:_[V],y:_[V+1],z:_[V+2]};q.push({v0:J,v1:Q,v2:C,i:H})}for(let H of q)this.renderTriangle(F,H.i,_,R,K,k,A)}renderTriangle(f,k,A,_,R,K,F){let q=f[k]*3,H=f[k+1]*3,W=f[k+2]*3,$={x:A[q],y:A[q+1],z:A[q+2]},V={x:A[H],y:A[H+1],z:A[H+2]},J={x:A[W],y:A[W+1],z:A[W+2]},Q=uf($,V,J,K,this.width,this.height);if(!Q)return;if(this.options.snapVertices)Q[0]=e(Q[0],5),Q[1]=e(Q[1],5),Q[2]=e(Q[2],5);if(Lf(Q[0],Q[1],Q[2],this.width,this.height))return;let C=Q[0].x,Y=Q[0].y,X=Q[1].x,U=Q[1].y,N=Q[2].x,Z=Q[2].y;if((X-C)*(Z-Y)-(U-Y)*(N-C)>0)return;let G=g(F,{x:$.x,y:$.y,z:$.z,w:1}),O=g(F,{x:V.x,y:V.y,z:V.z,w:1}),P=g(F,{x:J.x,y:J.y,z:J.z,w:1}),h=E({x:O.x,y:O.y,z:O.z},{x:G.x,y:G.y,z:G.z}),w=E({x:P.x,y:P.y,z:P.z},{x:G.x,y:G.y,z:G.z}),u=z(Q[0],q,f[k]*2,_,R),L=z(Q[1],H,f[k+1]*2,_,R),B=z(Q[2],W,f[k+2]*2,_,R);if(this.options.shading==="flat")this.renderFlatShading(u,L,B,h,w);else if(this.options.shading==="blinn-phong")this.renderBlinnPhongShading(u,L,B,$,V,J,_);else if(this.options.shading==="wireframe")return}renderFlatShading(f,k,A,_,R){let F=this.mainDirectionalLight.direction,q=T(F),H={x:200,y:120,z:60},W=0.85,$=T(y(_,R)),V=Math.max(0,b($,{x:-q.x,y:-q.y,z:-q.z}))*this.mainDirectionalLight.intensity,J={x:Math.max(0,Math.min(255,H.x*(0.15+0.85*V))),y:Math.max(0,Math.min(255,H.y*(0.15+0.85*V))),z:Math.max(0,Math.min(255,H.z*(0.15+0.85*V)))};this.drawTriangleScanline(f,k,A,J)}renderBlinnPhongShading(f,k,A,_,R,K,F){let q=T({x:-this.mainCamera.position.x,y:-this.mainCamera.position.y,z:-this.mainCamera.position.z}),H=[l(_,{x:F[0],y:F[1],z:F[2]},q,this.mainDirectionalLight),l(R,{x:F[3],y:F[4],z:F[5]},q,this.mainDirectionalLight),l(K,{x:F[6],y:F[7],z:F[8]},q,this.mainDirectionalLight)];f.color=[H[0].x,H[0].y,H[0].z],k.color=[H[1].x,H[1].y,H[1].z],A.color=[H[2].x,H[2].y,H[2].z],this.drawTriangleScanline(f,k,A)}clearZ(){this.zBuffer.fill(Number.POSITIVE_INFINITY)}clear(f=0,k=0,A=0,_=255){let R=this.packRGBA(f,k,A,_);this.data32.fill(R)}present(){if(!this.imageData)return;this.imageData.data.set(this.buf8),this.ctx.putImageData(this.imageData,0,0)}packRGBA(f,k,A,_=255){if(this.littleEndian)return _<<24|A<<16|k<<8|f;else return f<<24|k<<16|A<<8|_}setPixel(f,k,A,_,R,K=255){if(f<0||f>=this.width||k<0||k>=this.height)return;let F=k*this.width+f;this.data32[F]=this.packRGBA(A|0,_|0,R|0,K|0)}depthTest(f,k,A){let _=k*this.width+f;if(A>=this.zBuffer[_])return!1;return this.zBuffer[_]=A,!0}setCamera(f){this.mainCamera=f}setDirectionalLight(f){this.mainDirectionalLight=f}addModel(f){this.objModels.push(f)}}var df={shading:"flat",snapVertices:!1};async function mf(){let f=new Af("canvas",df),A=await new s().loadFromUrl("src/Examples/teddyBear.obj"),_=new ff({x:-50,y:0,z:0},{x:0,y:1,z:0},1);f.setCamera(_);let R=new kf({x:-1,y:-1,z:-1},{x:1,y:1,z:1},0.6);f.setDirectionalLight(R),f.addModel(A),f.start()}mf();