Files

14 lines
1.2 KiB
JavaScript

export const vec = {
sub:(a,b)=>a.map((v,i)=>v-b[i]),
add:(a,b)=>a.map((v,i)=>v+b[i]),
scale:(a,s)=>a.map(v=>v*s),
dot:(a,b)=>a.reduce((s,v,i)=>s+v*b[i],0),
cross:(a,b)=>[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]],
norm:a=>{const n=Math.hypot(...a);return n>1e-10?a.map(v=>v/n):[0,0,1];},
};
export function multiply(a,b){const out=new Float32Array(16);for(let c=0;c<4;c++)for(let r=0;r<4;r++)for(let k=0;k<4;k++)out[c*4+r]+=a[k*4+r]*b[c*4+k];return out;}
export function perspective(aspect,near,far){const f=1/Math.tan(Math.PI/9);return new Float32Array([f/aspect,0,0,0,0,f,0,0,0,0,(far+near)/(near-far),-1,0,0,2*far*near/(near-far),0]);}
export function lookAt(eye,target){const f=vec.norm(vec.sub(target,eye)),s=vec.norm(vec.cross(f,[0,0,1])),u=vec.cross(s,f);return new Float32Array([s[0],u[0],-f[0],0,s[1],u[1],-f[1],0,s[2],u[2],-f[2],0,-vec.dot(s,eye),-vec.dot(u,eye),vec.dot(f,eye),1]);}
export function project(p,m,width,height){const q=[...p,1],v=[0,0,0,0];for(let r=0;r<4;r++)for(let c=0;c<4;c++)v[r]+=m[c*4+r]*q[c];return{ x:(v[0]/v[3]+1)*width/2,y:(1-v[1]/v[3])*height/2,depth:v[2]/v[3],inFront:v[3]>0};}
export function hex(s){return [1,3,5].map(i=>parseInt(s.slice(i,i+2),16)/255);}