@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 3.93 kB
JavaScript
import{Vec3 as t}from"../math/vec3.js";const e=new t,s=new t,n=new t,a=new t,h=new t;class i{constructor(e=new t,s=new t(.5,.5,.5)){this.center=void 0,this.halfExtents=void 0,this._min=new t,this._max=new t,this.center=e,this.halfExtents=s}add(t){const e=this.center,s=e.x,n=e.y,a=e.z,h=this.halfExtents,i=h.x,x=h.y,r=h.z;let c=s-i,M=s+i,y=n-x,o=n+x,z=a-r,l=a+r;const u=t.center,m=u.x,b=u.y,E=u.z,f=t.halfExtents,d=f.x,A=f.y,_=f.z,g=m-d,p=m+d,L=b-A,N=b+A,U=E-_,V=E+_;g<c&&(c=g),p>M&&(M=p),L<y&&(y=L),N>o&&(o=N),U<z&&(z=U),V>l&&(l=V),e.x=.5*(c+M),e.y=.5*(y+o),e.z=.5*(z+l),h.x=.5*(M-c),h.y=.5*(o-y),h.z=.5*(l-z)}copy(t){this.center.copy(t.center),this.halfExtents.copy(t.halfExtents)}clone(){return new i(this.center.clone(),this.halfExtents.clone())}intersects(t){const e=this.getMax(),s=this.getMin(),n=t.getMax(),a=t.getMin();return s.x<=n.x&&e.x>=a.x&&s.y<=n.y&&e.y>=a.y&&s.z<=n.z&&e.z>=a.z}_intersectsRay(t,h){const i=e.copy(this.getMin()).sub(t.origin),x=s.copy(this.getMax()).sub(t.origin),r=t.direction;0===r.x?(i.x=i.x<0?-Number.MAX_VALUE:Number.MAX_VALUE,x.x=x.x<0?-Number.MAX_VALUE:Number.MAX_VALUE):(i.x/=r.x,x.x/=r.x),0===r.y?(i.y=i.y<0?-Number.MAX_VALUE:Number.MAX_VALUE,x.y=x.y<0?-Number.MAX_VALUE:Number.MAX_VALUE):(i.y/=r.y,x.y/=r.y),0===r.z?(i.z=i.z<0?-Number.MAX_VALUE:Number.MAX_VALUE,x.z=x.z<0?-Number.MAX_VALUE:Number.MAX_VALUE):(i.z/=r.z,x.z/=r.z);const c=n.set(Math.min(i.x,x.x),Math.min(i.y,x.y),Math.min(i.z,x.z)),M=a.set(Math.max(i.x,x.x),Math.max(i.y,x.y),Math.max(i.z,x.z)),y=Math.min(Math.min(M.x,M.y),M.z),o=Math.max(Math.max(c.x,c.y),c.z),z=y>=o&&o>=0;return z&&h.copy(t.direction).mulScalar(o).add(t.origin),z}_fastIntersectsRay(t){const i=e,x=s,r=n,c=a,M=h,y=t.direction;return i.sub2(t.origin,this.center),c.set(Math.abs(i.x),Math.abs(i.y),Math.abs(i.z)),r.mul2(i,y),!(c.x>this.halfExtents.x&&r.x>=0)&&(!(c.y>this.halfExtents.y&&r.y>=0)&&(!(c.z>this.halfExtents.z&&r.z>=0)&&(M.set(Math.abs(y.x),Math.abs(y.y),Math.abs(y.z)),x.cross(y,i),x.set(Math.abs(x.x),Math.abs(x.y),Math.abs(x.z)),!(x.x>this.halfExtents.y*M.z+this.halfExtents.z*M.y)&&(!(x.y>this.halfExtents.x*M.z+this.halfExtents.z*M.x)&&!(x.z>this.halfExtents.x*M.y+this.halfExtents.y*M.x)))))}intersectsRay(t,e){return e?this._intersectsRay(t,e):this._fastIntersectsRay(t)}setMinMax(t,e){this.center.add2(e,t).mulScalar(.5),this.halfExtents.sub2(e,t).mulScalar(.5)}getMin(){return this._min.copy(this.center).sub(this.halfExtents)}getMax(){return this._max.copy(this.center).add(this.halfExtents)}containsPoint(t){const e=this.getMin(),s=this.getMax();return!(t.x<e.x||t.x>s.x||t.y<e.y||t.y>s.y||t.z<e.z||t.z>s.z)}setFromTransformedAabb(t,e,s=!1){const n=t.center,a=t.halfExtents,h=e.data;let i=h[0],x=h[4],r=h[8],c=h[1],M=h[5],y=h[9],o=h[2],z=h[6],l=h[10];if(s){let t=i*i+x*x+r*r;if(t>0){const e=1/Math.sqrt(t);i*=e,x*=e,r*=e}if(t=c*c+M*M+y*y,t>0){const e=1/Math.sqrt(t);c*=e,M*=e,y*=e}if(t=o*o+z*z+l*l,t>0){const e=1/Math.sqrt(t);o*=e,z*=e,l*=e}}this.center.set(h[12]+i*n.x+x*n.y+r*n.z,h[13]+c*n.x+M*n.y+y*n.z,h[14]+o*n.x+z*n.y+l*n.z),this.halfExtents.set(Math.abs(i)*a.x+Math.abs(x)*a.y+Math.abs(r)*a.z,Math.abs(c)*a.x+Math.abs(M)*a.y+Math.abs(y)*a.z,Math.abs(o)*a.x+Math.abs(z)*a.y+Math.abs(l)*a.z)}static computeMinMax(t,e,s,n=t.length/3){if(n>0){let a=t[0],h=t[1],i=t[2],x=a,r=h,c=i;const M=3*n;for(let e=3;e<M;e+=3){const s=t[e],n=t[e+1],M=t[e+2];s<a&&(a=s),n<h&&(h=n),M<i&&(i=M),s>x&&(x=s),n>r&&(r=n),M>c&&(c=M)}e.set(a,h,i),s.set(x,r,c)}}compute(t,n){i.computeMinMax(t,e,s,n),this.setMinMax(e,s)}intersectsBoundingSphere(t){return this._distanceToBoundingSphereSq(t)<=t.radius*t.radius}_distanceToBoundingSphereSq(t){const e=this.getMin(),s=this.getMax();let n=0;const a=["x","y","z"];for(let h=0;h<3;++h){let i=0;const x=t.center[a[h]],r=e[a[h]],c=s[a[h]];let M=0;x<r&&(M=r-x,i+=M*M),x>c&&(M=x-c,i+=M*M),n+=i}return n}_expand(t,n){e.add2(this.getMin(),t),s.add2(this.getMax(),n),this.setMinMax(e,s)}}export{i as BoundingBox};