@c-frame/aframe-physics-system
Version:
Physics system for A-Frame VR, built on Cannon.js & Ammo.js
1 lines • 302 kB
JavaScript
!function(){return function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){return o(e[i][1][r]||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}}()({1:[function(require,module,exports){var CANNON=require("cannon-es");require("./src/components/math"),require("./src/components/body/ammo-body"),require("./src/components/body/body"),require("./src/components/body/dynamic-body"),require("./src/components/body/static-body"),require("./src/components/shape/shape"),require("./src/components/shape/ammo-shape"),require("./src/components/ammo-constraint"),require("./src/components/constraint"),require("./src/components/spring"),require("./src/system"),module.exports={registerAll:function(){console.warn("registerAll() is deprecated. Components are automatically registered.")}},window.CANNON=window.CANNON||CANNON},{"./src/components/ammo-constraint":9,"./src/components/body/ammo-body":10,"./src/components/body/body":11,"./src/components/body/dynamic-body":12,"./src/components/body/static-body":13,"./src/components/constraint":14,"./src/components/math":15,"./src/components/shape/ammo-shape":17,"./src/components/shape/shape":18,"./src/components/spring":19,"./src/system":29,"cannon-es":5}],2:[function(require,module,exports){var CANNON=require("cannon-es");CANNON.shape2mesh=function(body){var obj=new THREE.Object3D;function createBufferGeometry(positions,faces){var geometry=new THREE.BufferGeometry;return geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions,3)),geometry.setIndex(faces),geometry.computeBoundingSphere(),geometry}for(var l=0;l<body.shapes.length;l++){var mesh,shape=body.shapes[l];switch(shape.type){case CANNON.Shape.types.SPHERE:var sphere_geometry=new THREE.SphereGeometry(shape.radius,8,8);mesh=new THREE.Mesh(sphere_geometry,this.currentMaterial);break;case CANNON.Shape.types.PARTICLE:mesh=new THREE.Mesh(this.particleGeo,this.particleMaterial);var s=this.settings;mesh.scale.set(s.particleSize,s.particleSize,s.particleSize);break;case CANNON.Shape.types.PLANE:var geometry=new THREE.PlaneGeometry(10,10,4,4);mesh=new THREE.Object3D;var submesh=new THREE.Object3D,ground=new THREE.Mesh(geometry,this.currentMaterial);ground.scale.set(100,100,100),submesh.add(ground),ground.castShadow=!0,ground.receiveShadow=!0,mesh.add(submesh);break;case CANNON.Shape.types.BOX:var box_geometry=new THREE.BoxGeometry(2*shape.halfExtents.x,2*shape.halfExtents.y,2*shape.halfExtents.z);mesh=new THREE.Mesh(box_geometry,this.currentMaterial);break;case CANNON.Shape.types.CONVEXPOLYHEDRON:for(var positions=[],i=0;i<shape.vertices.length;i++){var v=shape.vertices[i];positions.push(v.x,v.y,v.z)}var faces=[];for(i=0;i<shape.faces.length;i++)for(var face=shape.faces[i],a=face[0],j=1;j<face.length-1;j++){var b=face[j],c=face[j+1];faces.push(a,b,c)}var geo=createBufferGeometry(positions,faces);mesh=new THREE.Mesh(geo,this.currentMaterial);break;case CANNON.Shape.types.HEIGHTFIELD:for(var v0=new CANNON.Vec3,v1=new CANNON.Vec3,v2=new CANNON.Vec3,xi=(positions=[],faces=[],0);xi<shape.data.length-1;xi++)for(var yi=0;yi<shape.data[xi].length-1;yi++)for(var k=0;k<2;k++){shape.getConvexTrianglePillar(xi,yi,0===k),v0.copy(shape.pillarConvex.vertices[0]),v1.copy(shape.pillarConvex.vertices[1]),v2.copy(shape.pillarConvex.vertices[2]),v0.vadd(shape.pillarOffset,v0),v1.vadd(shape.pillarOffset,v1),v2.vadd(shape.pillarOffset,v2),positions.push(v0.x,v0.y,v0.z,v1.x,v1.y,v1.z,v2.x,v2.y,v2.z);i=positions.length/3-3;faces.push(i,i+1,i+2)}geometry=createBufferGeometry(positions,faces);mesh=new THREE.Mesh(geometry,this.currentMaterial);break;case CANNON.Shape.types.TRIMESH:for(geometry=new THREE.BufferGeometry,v0=new CANNON.Vec3,v1=new CANNON.Vec3,v2=new CANNON.Vec3,positions=[],faces=[],i=0;i<shape.indices.length/3;i++){shape.getTriangleVertices(i,v0,v1,v2),positions.push(v0.x,v0.y,v0.z,v1.x,v1.y,v1.z,v2.x,v2.y,v2.z);j=positions.length/3-3;faces.push(j,j+1,j+2)}geometry=createBufferGeometry(positions,faces);mesh=new THREE.Mesh(geometry,this.currentMaterial);break;default:throw"Visual type not recognized: "+shape.type}if(mesh.receiveShadow=!0,mesh.castShadow=!0,mesh.children)for(i=0;i<mesh.children.length;i++)if(mesh.children[i].castShadow=!0,mesh.children[i].receiveShadow=!0,mesh.children[i])for(j=0;j<mesh.children[i].length;j++)mesh.children[i].children[j].castShadow=!0,mesh.children[i].children[j].receiveShadow=!0;var o=body.shapeOffsets[l],q=body.shapeOrientations[l];mesh.position.set(o.x,o.y,o.z),mesh.quaternion.set(q.x,q.y,q.z,q.w),obj.add(mesh)}return obj},module.exports=CANNON.shape2mesh},{"cannon-es":5}],3:[function(require,module,exports){AFRAME.registerComponent("stats-panel",{schema:{merge:{type:"boolean",default:!0}},init(){const container=document.querySelector(".rs-container");if(container&&this.data.merge)return void(this.container=container);this.base=document.createElement("div"),this.base.classList.add("rs-base");const body=document.body||document.getElementsByTagName("body")[0];container&&!this.data.merge&&(this.base.style.top="auto",this.base.style.bottom="20px"),body.appendChild(this.base),this.container=document.createElement("div"),this.container.classList.add("rs-container"),this.base.appendChild(this.container)}}),AFRAME.registerComponent("stats-group",{multiple:!0,schema:{label:{type:"string"}},init(){let container;const baseComponent=this.el.components["stats-panel"];(container=baseComponent?baseComponent.container:document.querySelector(".rs-container"))?(this.groupHeader=document.createElement("h1"),this.groupHeader.innerHTML=this.data.label,container.appendChild(this.groupHeader),this.group=document.createElement("div"),this.group.classList.add("rs-group"),this.group.style.flexDirection="column",this.group.style.webKitFlexDirection="column",container.appendChild(this.group)):console.warn("Couldn't find stats container to add stats to.\n Add either stats or stats-panel component to a-scene")}}),AFRAME.registerComponent("stats-row",{multiple:!0,schema:{group:{type:"string"},event:{type:"string"},properties:{type:"array"},label:{type:"string"}},init(){const groupComponentName="stats-group__"+this.data.group,groupComponent=this.el.components[groupComponentName]||this.el.sceneEl.components[groupComponentName]||this.el.components["stats-group"]||this.el.sceneEl.components["stats-group"];groupComponent?(this.counter=document.createElement("div"),this.counter.classList.add("rs-counter-base"),groupComponent.group.appendChild(this.counter),this.counterId=document.createElement("div"),this.counterId.classList.add("rs-counter-id"),this.counterId.innerHTML=this.data.label,this.counter.appendChild(this.counterId),this.counterValues={},this.data.properties.forEach(property=>{const counterValue=document.createElement("div");counterValue.classList.add("rs-counter-value"),counterValue.innerHTML="...",this.counter.appendChild(counterValue),this.counterValues[property]=counterValue}),this.updateStatsData=this.updateStatsData.bind(this),this.el.addEventListener(this.data.event,this.updateStatsData),this.splitCache={}):console.warn(`Couldn't find stats group ${groupComponentName}`)},updateStatsData(e){this.data.properties&&this.data.properties.forEach(property=>{const split=this.splitDot(property);let value=e.detail;for(i=0;i<split.length;i++)value=value[split[i]];this.counterValues[property].innerHTML=value})},splitDot(path){return path in this.splitCache?this.splitCache[path]:(this.splitCache[path]=path.split("."),this.splitCache[path])}}),AFRAME.registerComponent("stats-collector",{multiple:!0,schema:{inEvent:{type:"string"},properties:{type:"array"},outputFrequency:{type:"number",default:100},outEvent:{type:"string"},outputs:{type:"array"},outputToConsole:{type:"string"}},init(){this.statsData={},this.resetData(),this.outputDetail={},this.data.properties.forEach(property=>{this.outputDetail[property]={}}),this.statsReceived=this.statsReceived.bind(this),this.el.addEventListener(this.data.inEvent,this.statsReceived)},resetData(){this.counter=0,this.data.properties.forEach(property=>{this.statsData[property]=[]})},statsReceived(e){this.updateStatsData(e.detail),this.counter++,this.counter===this.data.outputFrequency&&(this.outputData(),this.resetData())},updateStatsData(detail){this.data.properties.forEach(property=>{let value=detail;value=value[property],this.statsData[property].push(value)})},outputData(){this.data.properties.forEach(property=>{this.data.outputs.forEach(output=>{this.outputDetail[property][output]=this.computeOutput(output,this.statsData[property])})}),this.data.outEvent&&this.el.emit(this.data.outEvent,this.outputDetail),this.data.outputToConsole&&console.log(this.data.outputToConsole,this.outputDetail)},computeOutput(outputInstruction,data){const outputInstructions=outputInstruction.split("__");let output;switch(outputInstructions[0]){case"mean":output=data.reduce((a,b)=>a+b,0)/data.length;break;case"max":output=Math.max(...data);break;case"min":output=Math.min(...data);break;case"percentile":const sorted=data.sort((a,b)=>a-b),proportion=+outputInstructions[1].replace("_",".")/100,position=(data.length-1)*proportion,base=Math.floor(position),delta=position-base;output=void 0!==sorted[base+1]?sorted[base]+delta*(sorted[base+1]-sorted[base]):sorted[base]}return output.toFixed(2)}})},{}],4:[function(require,module,exports){THREE.AmmoDebugConstants={NoDebug:0,DrawWireframe:1,DrawAabb:2,DrawFeaturesText:4,DrawContactPoints:8,NoDeactivation:16,NoHelpText:32,DrawText:64,ProfileTimings:128,EnableSatComparison:256,DisableBulletLCP:512,EnableCCD:1024,DrawConstraints:2048,DrawConstraintLimits:4096,FastWireframe:8192,DrawNormals:16384,DrawOnTop:32768,MAX_DEBUG_DRAW_MODE:4294967295},THREE.AmmoDebugDrawer=function(scene,world,options){this.scene=scene,this.world=world,options=options||{},this.debugDrawMode=options.debugDrawMode||THREE.AmmoDebugConstants.DrawWireframe;var drawOnTop=this.debugDrawMode&THREE.AmmoDebugConstants.DrawOnTop||!1,maxBufferSize=options.maxBufferSize||1e6;this.geometry=new THREE.BufferGeometry;var vertices=new Float32Array(3*maxBufferSize),colors=new Float32Array(3*maxBufferSize);this.geometry.setAttribute("position",new THREE.BufferAttribute(vertices,3).setUsage(THREE.DynamicDrawUsage)),this.geometry.setAttribute("color",new THREE.BufferAttribute(colors,3).setUsage(THREE.DynamicDrawUsage)),this.index=0;var material=new THREE.LineBasicMaterial({vertexColors:!0,depthTest:!drawOnTop});this.mesh=new THREE.LineSegments(this.geometry,material),drawOnTop&&(this.mesh.renderOrder=999),this.mesh.frustumCulled=!1,this.enabled=!1,this.debugDrawer=new Ammo.DebugDrawer,this.debugDrawer.drawLine=this.drawLine.bind(this),this.debugDrawer.drawContactPoint=this.drawContactPoint.bind(this),this.debugDrawer.reportErrorWarning=this.reportErrorWarning.bind(this),this.debugDrawer.draw3dText=this.draw3dText.bind(this),this.debugDrawer.setDebugMode=this.setDebugMode.bind(this),this.debugDrawer.getDebugMode=this.getDebugMode.bind(this),this.debugDrawer.enable=this.enable.bind(this),this.debugDrawer.disable=this.disable.bind(this),this.debugDrawer.update=this.update.bind(this),this.world.setDebugDrawer(this.debugDrawer)},THREE.AmmoDebugDrawer.prototype=function(){return this.debugDrawer},THREE.AmmoDebugDrawer.prototype.enable=function(){this.enabled=!0,this.scene.add(this.mesh)},THREE.AmmoDebugDrawer.prototype.disable=function(){this.enabled=!1,this.scene.remove(this.mesh)},THREE.AmmoDebugDrawer.prototype.update=function(){this.enabled&&(0!=this.index&&(this.geometry.attributes.position.needsUpdate=!0,this.geometry.attributes.color.needsUpdate=!0),this.index=0,this.world.debugDrawWorld(),this.geometry.setDrawRange(0,this.index))},THREE.AmmoDebugDrawer.prototype.drawLine=function(from,to,color){const heap=Ammo.HEAPF32,r=heap[(color+0)/4],g=heap[(color+4)/4],b=heap[(color+8)/4],fromX=heap[(from+0)/4],fromY=heap[(from+4)/4],fromZ=heap[(from+8)/4];this.geometry.attributes.position.setXYZ(this.index,fromX,fromY,fromZ),this.geometry.attributes.color.setXYZ(this.index++,r,g,b);const toX=heap[(to+0)/4],toY=heap[(to+4)/4],toZ=heap[(to+8)/4];this.geometry.attributes.position.setXYZ(this.index,toX,toY,toZ),this.geometry.attributes.color.setXYZ(this.index++,r,g,b)},THREE.AmmoDebugDrawer.prototype.drawContactPoint=function(pointOnB,normalOnB,distance,lifeTime,color){const heap=Ammo.HEAPF32,r=heap[(color+0)/4],g=heap[(color+4)/4],b=heap[(color+8)/4],x=heap[(pointOnB+0)/4],y=heap[(pointOnB+4)/4],z=heap[(pointOnB+8)/4];this.geometry.attributes.position.setXYZ(this.index,x,y,z),this.geometry.attributes.color.setXYZ(this.index++,r,g,b);const dx=heap[(normalOnB+0)/4]*distance,dy=heap[(normalOnB+4)/4]*distance,dz=heap[(normalOnB+8)/4]*distance;this.geometry.attributes.position.setXYZ(this.index,x+dx,y+dy,z+dz),this.geometry.attributes.color.setXYZ(this.index++,r,g,b)},THREE.AmmoDebugDrawer.prototype.reportErrorWarning=function(warningString){Ammo.hasOwnProperty("Pointer_stringify")?console.warn(Ammo.Pointer_stringify(warningString)):this.warnedOnce||(this.warnedOnce=!0,console.warn("Cannot print warningString, please rebuild Ammo.js using 'debug' flag"))},THREE.AmmoDebugDrawer.prototype.draw3dText=function(location,textString){console.warn("TODO: draw3dText")},THREE.AmmoDebugDrawer.prototype.setDebugMode=function(debugMode){this.debugDrawMode=debugMode},THREE.AmmoDebugDrawer.prototype.getDebugMode=function(){return this.debugDrawMode}},{}],5:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.World=exports.Vec3Pool=exports.Vec3=exports.Trimesh=exports.Transform=exports.Spring=exports.SplitSolver=exports.Sphere=exports.Solver=exports.Shape=exports.SPHSystem=exports.SHAPE_TYPES=exports.SAPBroadphase=exports.RotationalMotorEquation=exports.RotationalEquation=exports.RigidVehicle=exports.RaycastVehicle=exports.RaycastResult=exports.Ray=exports.RAY_MODES=exports.Quaternion=exports.Pool=exports.PointToPointConstraint=exports.Plane=exports.Particle=exports.ObjectCollisionMatrix=exports.Narrowphase=exports.NaiveBroadphase=exports.Material=exports.Mat3=exports.LockConstraint=exports.JacobianElement=exports.HingeConstraint=exports.Heightfield=exports.GridBroadphase=exports.GSSolver=exports.FrictionEquation=exports.EventTarget=exports.Equation=exports.DistanceConstraint=exports.Cylinder=exports.ConvexPolyhedron=exports.ContactMaterial=exports.ContactEquation=exports.Constraint=exports.ConeTwistConstraint=exports.COLLISION_TYPES=exports.Broadphase=exports.Box=exports.Body=exports.BODY_TYPES=exports.BODY_SLEEP_STATES=exports.ArrayCollisionMatrix=exports.AABB=void 0;exports.ObjectCollisionMatrix=class{constructor(){this.matrix={}}get(bi,bj){let{id:i}=bi,{id:j}=bj;if(j>i){const temp=j;j=i,i=temp}return i+"-"+j in this.matrix}set(bi,bj,value){let{id:i}=bi,{id:j}=bj;if(j>i){const temp=j;j=i,i=temp}value?this.matrix[i+"-"+j]=!0:delete this.matrix[i+"-"+j]}reset(){this.matrix={}}setNumObjects(n){}};class Mat3{constructor(elements=[0,0,0,0,0,0,0,0,0]){this.elements=elements}identity(){const e=this.elements;e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1}setZero(){const e=this.elements;e[0]=0,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=0,e[6]=0,e[7]=0,e[8]=0}setTrace(vector){const e=this.elements;e[0]=vector.x,e[4]=vector.y,e[8]=vector.z}getTrace(target=new Vec3){const e=this.elements;target.x=e[0],target.y=e[4],target.z=e[8]}vmult(v,target=new Vec3){const e=this.elements,x=v.x,y=v.y,z=v.z;return target.x=e[0]*x+e[1]*y+e[2]*z,target.y=e[3]*x+e[4]*y+e[5]*z,target.z=e[6]*x+e[7]*y+e[8]*z,target}smult(s){for(let i=0;i<this.elements.length;i++)this.elements[i]*=s}mmult(matrix,target=new Mat3){const{elements:elements}=matrix;for(let i=0;i<3;i++)for(let j=0;j<3;j++){let sum=0;for(let k=0;k<3;k++)sum+=elements[i+3*k]*this.elements[k+3*j];target.elements[i+3*j]=sum}return target}scale(vector,target=new Mat3){const e=this.elements,t=target.elements;for(let i=0;3!==i;i++)t[3*i+0]=vector.x*e[3*i+0],t[3*i+1]=vector.y*e[3*i+1],t[3*i+2]=vector.z*e[3*i+2];return target}solve(b,target=new Vec3){const eqns=[];let i,j;for(i=0;i<12;i++)eqns.push(0);for(i=0;i<3;i++)for(j=0;j<3;j++)eqns[i+4*j]=this.elements[i+3*j];eqns[3]=b.x,eqns[7]=b.y,eqns[11]=b.z;let n=3;const k=n;let np;let p;do{if(0===eqns[(i=k-n)+4*i])for(j=i+1;j<k;j++)if(0!==eqns[i+4*j]){np=4;do{eqns[(p=4-np)+4*i]+=eqns[p+4*j]}while(--np);break}if(0!==eqns[i+4*i])for(j=i+1;j<k;j++){const multiplier=eqns[i+4*j]/eqns[i+4*i];np=4;do{eqns[(p=4-np)+4*j]=p<=i?0:eqns[p+4*j]-eqns[p+4*i]*multiplier}while(--np)}}while(--n);if(target.z=eqns[11]/eqns[10],target.y=(eqns[7]-eqns[6]*target.z)/eqns[5],target.x=(eqns[3]-eqns[2]*target.z-eqns[1]*target.y)/eqns[0],isNaN(target.x)||isNaN(target.y)||isNaN(target.z)||target.x===1/0||target.y===1/0||target.z===1/0)throw"Could not solve equation! Got x=["+target.toString()+"], b=["+b.toString()+"], A=["+this.toString()+"]";return target}e(row,column,value){if(void 0===value)return this.elements[column+3*row];this.elements[column+3*row]=value}copy(matrix){for(let i=0;i<matrix.elements.length;i++)this.elements[i]=matrix.elements[i];return this}toString(){let r="";for(let i=0;i<9;i++)r+=this.elements[i]+",";return r}reverse(target=new Mat3){const eqns=[];let i,j;for(i=0;i<18;i++)eqns.push(0);for(i=0;i<3;i++)for(j=0;j<3;j++)eqns[i+6*j]=this.elements[i+3*j];eqns[3]=1,eqns[9]=0,eqns[15]=0,eqns[4]=0,eqns[10]=1,eqns[16]=0,eqns[5]=0,eqns[11]=0,eqns[17]=1;let n=3;const k=n;let np;let p;do{if(0===eqns[(i=k-n)+6*i])for(j=i+1;j<k;j++)if(0!==eqns[i+6*j]){np=6;do{eqns[(p=6-np)+6*i]+=eqns[p+6*j]}while(--np);break}if(0!==eqns[i+6*i])for(j=i+1;j<k;j++){const multiplier=eqns[i+6*j]/eqns[i+6*i];np=6;do{eqns[(p=6-np)+6*j]=p<=i?0:eqns[p+6*j]-eqns[p+6*i]*multiplier}while(--np)}}while(--n);i=2;do{j=i-1;do{const multiplier=eqns[i+6*j]/eqns[i+6*i];np=6;do{eqns[(p=6-np)+6*j]=eqns[p+6*j]-eqns[p+6*i]*multiplier}while(--np)}while(j--)}while(--i);i=2;do{const multiplier=1/eqns[i+6*i];np=6;do{eqns[(p=6-np)+6*i]=eqns[p+6*i]*multiplier}while(--np)}while(i--);i=2;do{j=2;do{if(p=eqns[3+j+6*i],isNaN(p)||p===1/0)throw"Could not reverse! A=["+this.toString()+"]";target.e(i,j,p)}while(j--)}while(i--);return target}setRotationFromQuaternion(q){const x=q.x,y=q.y,z=q.z,w=q.w,x2=x+x,y2=y+y,z2=z+z,xx=x*x2,xy=x*y2,xz=x*z2,yy=y*y2,yz=y*z2,zz=z*z2,wx=w*x2,wy=w*y2,wz=w*z2,e=this.elements;return e[0]=1-(yy+zz),e[1]=xy-wz,e[2]=xz+wy,e[3]=xy+wz,e[4]=1-(xx+zz),e[5]=yz-wx,e[6]=xz-wy,e[7]=yz+wx,e[8]=1-(xx+yy),this}transpose(target=new Mat3){const Mt=target.elements,M=this.elements;for(let i=0;3!==i;i++)for(let j=0;3!==j;j++)Mt[3*i+j]=M[3*j+i];return target}}exports.Mat3=Mat3;class Vec3{constructor(x=0,y=0,z=0){this.x=x,this.y=y,this.z=z}cross(vector,target=new Vec3){const vx=vector.x,vy=vector.y,vz=vector.z,x=this.x,y=this.y,z=this.z;return target.x=y*vz-z*vy,target.y=z*vx-x*vz,target.z=x*vy-y*vx,target}set(x,y,z){return this.x=x,this.y=y,this.z=z,this}setZero(){this.x=this.y=this.z=0}vadd(vector,target){if(!target)return new Vec3(this.x+vector.x,this.y+vector.y,this.z+vector.z);target.x=vector.x+this.x,target.y=vector.y+this.y,target.z=vector.z+this.z}vsub(vector,target){if(!target)return new Vec3(this.x-vector.x,this.y-vector.y,this.z-vector.z);target.x=this.x-vector.x,target.y=this.y-vector.y,target.z=this.z-vector.z}crossmat(){return new Mat3([0,-this.z,this.y,this.z,0,-this.x,-this.y,this.x,0])}normalize(){const x=this.x,y=this.y,z=this.z,n=Math.sqrt(x*x+y*y+z*z);if(n>0){const invN=1/n;this.x*=invN,this.y*=invN,this.z*=invN}else this.x=0,this.y=0,this.z=0;return n}unit(target=new Vec3){const x=this.x,y=this.y,z=this.z;let ninv=Math.sqrt(x*x+y*y+z*z);return ninv>0?(ninv=1/ninv,target.x=x*ninv,target.y=y*ninv,target.z=z*ninv):(target.x=1,target.y=0,target.z=0),target}length(){const x=this.x,y=this.y,z=this.z;return Math.sqrt(x*x+y*y+z*z)}lengthSquared(){return this.dot(this)}distanceTo(p){const x=this.x,y=this.y,z=this.z,px=p.x,py=p.y,pz=p.z;return Math.sqrt((px-x)*(px-x)+(py-y)*(py-y)+(pz-z)*(pz-z))}distanceSquared(p){const x=this.x,y=this.y,z=this.z,px=p.x,py=p.y,pz=p.z;return(px-x)*(px-x)+(py-y)*(py-y)+(pz-z)*(pz-z)}scale(scalar,target=new Vec3){const x=this.x,y=this.y,z=this.z;return target.x=scalar*x,target.y=scalar*y,target.z=scalar*z,target}vmul(vector,target=new Vec3){return target.x=vector.x*this.x,target.y=vector.y*this.y,target.z=vector.z*this.z,target}addScaledVector(scalar,vector,target=new Vec3){return target.x=this.x+scalar*vector.x,target.y=this.y+scalar*vector.y,target.z=this.z+scalar*vector.z,target}dot(vector){return this.x*vector.x+this.y*vector.y+this.z*vector.z}isZero(){return 0===this.x&&0===this.y&&0===this.z}negate(target=new Vec3){return target.x=-this.x,target.y=-this.y,target.z=-this.z,target}tangents(t1,t2){const norm=this.length();if(norm>0){const n=Vec3_tangents_n,inorm=1/norm;n.set(this.x*inorm,this.y*inorm,this.z*inorm);const randVec=Vec3_tangents_randVec;Math.abs(n.x)<.9?(randVec.set(1,0,0),n.cross(randVec,t1)):(randVec.set(0,1,0),n.cross(randVec,t1)),n.cross(t1,t2)}else t1.set(1,0,0),t2.set(0,1,0)}toString(){return this.x+","+this.y+","+this.z}toArray(){return[this.x,this.y,this.z]}copy(vector){return this.x=vector.x,this.y=vector.y,this.z=vector.z,this}lerp(vector,t,target){const x=this.x,y=this.y,z=this.z;target.x=x+(vector.x-x)*t,target.y=y+(vector.y-y)*t,target.z=z+(vector.z-z)*t}almostEquals(vector,precision=1e-6){return!(Math.abs(this.x-vector.x)>precision||Math.abs(this.y-vector.y)>precision||Math.abs(this.z-vector.z)>precision)}almostZero(precision=1e-6){return!(Math.abs(this.x)>precision||Math.abs(this.y)>precision||Math.abs(this.z)>precision)}isAntiparallelTo(vector,precision){return this.negate(antip_neg),antip_neg.almostEquals(vector,precision)}clone(){return new Vec3(this.x,this.y,this.z)}}exports.Vec3=Vec3,Vec3.ZERO=new Vec3(0,0,0),Vec3.UNIT_X=new Vec3(1,0,0),Vec3.UNIT_Y=new Vec3(0,1,0),Vec3.UNIT_Z=new Vec3(0,0,1);const Vec3_tangents_n=new Vec3,Vec3_tangents_randVec=new Vec3,antip_neg=new Vec3;class AABB{constructor(options={}){this.lowerBound=new Vec3,this.upperBound=new Vec3,options.lowerBound&&this.lowerBound.copy(options.lowerBound),options.upperBound&&this.upperBound.copy(options.upperBound)}setFromPoints(points,position,quaternion,skinSize){const l=this.lowerBound,u=this.upperBound,q=quaternion;l.copy(points[0]),q&&q.vmult(l,l),u.copy(l);for(let i=1;i<points.length;i++){let p=points[i];q&&(q.vmult(p,tmp),p=tmp),p.x>u.x&&(u.x=p.x),p.x<l.x&&(l.x=p.x),p.y>u.y&&(u.y=p.y),p.y<l.y&&(l.y=p.y),p.z>u.z&&(u.z=p.z),p.z<l.z&&(l.z=p.z)}return position&&(position.vadd(l,l),position.vadd(u,u)),skinSize&&(l.x-=skinSize,l.y-=skinSize,l.z-=skinSize,u.x+=skinSize,u.y+=skinSize,u.z+=skinSize),this}copy(aabb){return this.lowerBound.copy(aabb.lowerBound),this.upperBound.copy(aabb.upperBound),this}clone(){return(new AABB).copy(this)}extend(aabb){this.lowerBound.x=Math.min(this.lowerBound.x,aabb.lowerBound.x),this.upperBound.x=Math.max(this.upperBound.x,aabb.upperBound.x),this.lowerBound.y=Math.min(this.lowerBound.y,aabb.lowerBound.y),this.upperBound.y=Math.max(this.upperBound.y,aabb.upperBound.y),this.lowerBound.z=Math.min(this.lowerBound.z,aabb.lowerBound.z),this.upperBound.z=Math.max(this.upperBound.z,aabb.upperBound.z)}overlaps(aabb){const l1=this.lowerBound,u1=this.upperBound,l2=aabb.lowerBound,u2=aabb.upperBound,overlapsX=l2.x<=u1.x&&u1.x<=u2.x||l1.x<=u2.x&&u2.x<=u1.x,overlapsY=l2.y<=u1.y&&u1.y<=u2.y||l1.y<=u2.y&&u2.y<=u1.y,overlapsZ=l2.z<=u1.z&&u1.z<=u2.z||l1.z<=u2.z&&u2.z<=u1.z;return overlapsX&&overlapsY&&overlapsZ}volume(){const l=this.lowerBound,u=this.upperBound;return(u.x-l.x)*(u.y-l.y)*(u.z-l.z)}contains(aabb){const l1=this.lowerBound,u1=this.upperBound,l2=aabb.lowerBound,u2=aabb.upperBound;return l1.x<=l2.x&&u1.x>=u2.x&&l1.y<=l2.y&&u1.y>=u2.y&&l1.z<=l2.z&&u1.z>=u2.z}getCorners(a,b,c,d,e,f,g,h){const l=this.lowerBound,u=this.upperBound;a.copy(l),b.set(u.x,l.y,l.z),c.set(u.x,u.y,l.z),d.set(l.x,u.y,u.z),e.set(u.x,l.y,u.z),f.set(l.x,u.y,l.z),g.set(l.x,l.y,u.z),h.copy(u)}toLocalFrame(frame,target){const corners=transformIntoFrame_corners,a=corners[0],b=corners[1],c=corners[2],d=corners[3],e=corners[4],f=corners[5],g=corners[6],h=corners[7];this.getCorners(a,b,c,d,e,f,g,h);for(let i=0;8!==i;i++){const corner=corners[i];frame.pointToLocal(corner,corner)}return target.setFromPoints(corners)}toWorldFrame(frame,target){const corners=transformIntoFrame_corners,a=corners[0],b=corners[1],c=corners[2],d=corners[3],e=corners[4],f=corners[5],g=corners[6],h=corners[7];this.getCorners(a,b,c,d,e,f,g,h);for(let i=0;8!==i;i++){const corner=corners[i];frame.pointToWorld(corner,corner)}return target.setFromPoints(corners)}overlapsRay(ray){const{direction:direction,from:from}=ray,dirFracX=1/direction.x,dirFracY=1/direction.y,dirFracZ=1/direction.z,t1=(this.lowerBound.x-from.x)*dirFracX,t2=(this.upperBound.x-from.x)*dirFracX,t3=(this.lowerBound.y-from.y)*dirFracY,t4=(this.upperBound.y-from.y)*dirFracY,t5=(this.lowerBound.z-from.z)*dirFracZ,t6=(this.upperBound.z-from.z)*dirFracZ,tmin=Math.max(Math.max(Math.min(t1,t2),Math.min(t3,t4)),Math.min(t5,t6)),tmax=Math.min(Math.min(Math.max(t1,t2),Math.max(t3,t4)),Math.max(t5,t6));return!(tmax<0)&&!(tmin>tmax)}}exports.AABB=AABB;const tmp=new Vec3,transformIntoFrame_corners=[new Vec3,new Vec3,new Vec3,new Vec3,new Vec3,new Vec3,new Vec3,new Vec3];class ArrayCollisionMatrix{constructor(){this.matrix=[]}get(bi,bj){let{index:i}=bi,{index:j}=bj;if(j>i){const temp=j;j=i,i=temp}return this.matrix[(i*(i+1)>>1)+j-1]}set(bi,bj,value){let{index:i}=bi,{index:j}=bj;if(j>i){const temp=j;j=i,i=temp}this.matrix[(i*(i+1)>>1)+j-1]=value?1:0}reset(){for(let i=0,l=this.matrix.length;i!==l;i++)this.matrix[i]=0}setNumObjects(n){this.matrix.length=n*(n-1)>>1}}exports.ArrayCollisionMatrix=ArrayCollisionMatrix;class EventTarget{constructor(){}addEventListener(type,listener){void 0===this._listeners&&(this._listeners={});const listeners=this._listeners;return void 0===listeners[type]&&(listeners[type]=[]),listeners[type].includes(listener)||listeners[type].push(listener),this}hasEventListener(type,listener){if(void 0===this._listeners)return!1;const listeners=this._listeners;return!(void 0===listeners[type]||!listeners[type].includes(listener))}hasAnyEventListener(type){if(void 0===this._listeners)return!1;return void 0!==this._listeners[type]}removeEventListener(type,listener){if(void 0===this._listeners)return this;const listeners=this._listeners;if(void 0===listeners[type])return this;const index=listeners[type].indexOf(listener);return-1!==index&&listeners[type].splice(index,1),this}dispatchEvent(event){if(void 0===this._listeners)return this;const listenerArray=this._listeners[event.type];if(void 0!==listenerArray){event.target=this;for(let i=0,l=listenerArray.length;i<l;i++)listenerArray[i].call(this,event)}return this}}exports.EventTarget=EventTarget;class Quaternion{constructor(x=0,y=0,z=0,w=1){this.x=x,this.y=y,this.z=z,this.w=w}set(x,y,z,w){return this.x=x,this.y=y,this.z=z,this.w=w,this}toString(){return this.x+","+this.y+","+this.z+","+this.w}toArray(){return[this.x,this.y,this.z,this.w]}setFromAxisAngle(vector,angle){const s=Math.sin(.5*angle);return this.x=vector.x*s,this.y=vector.y*s,this.z=vector.z*s,this.w=Math.cos(.5*angle),this}toAxisAngle(targetAxis=new Vec3){this.normalize();const angle=2*Math.acos(this.w),s=Math.sqrt(1-this.w*this.w);return s<.001?(targetAxis.x=this.x,targetAxis.y=this.y,targetAxis.z=this.z):(targetAxis.x=this.x/s,targetAxis.y=this.y/s,targetAxis.z=this.z/s),[targetAxis,angle]}setFromVectors(u,v){if(u.isAntiparallelTo(v)){const t1=sfv_t1,t2=sfv_t2;u.tangents(t1,t2),this.setFromAxisAngle(t1,Math.PI)}else{const a=u.cross(v);this.x=a.x,this.y=a.y,this.z=a.z,this.w=Math.sqrt(u.length()**2*v.length()**2)+u.dot(v),this.normalize()}return this}mult(quat,target=new Quaternion){const ax=this.x,ay=this.y,az=this.z,aw=this.w,bx=quat.x,by=quat.y,bz=quat.z,bw=quat.w;return target.x=ax*bw+aw*bx+ay*bz-az*by,target.y=ay*bw+aw*by+az*bx-ax*bz,target.z=az*bw+aw*bz+ax*by-ay*bx,target.w=aw*bw-ax*bx-ay*by-az*bz,target}inverse(target=new Quaternion){const x=this.x,y=this.y,z=this.z,w=this.w;this.conjugate(target);const inorm2=1/(x*x+y*y+z*z+w*w);return target.x*=inorm2,target.y*=inorm2,target.z*=inorm2,target.w*=inorm2,target}conjugate(target=new Quaternion){return target.x=-this.x,target.y=-this.y,target.z=-this.z,target.w=this.w,target}normalize(){let l=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);return 0===l?(this.x=0,this.y=0,this.z=0,this.w=0):(l=1/l,this.x*=l,this.y*=l,this.z*=l,this.w*=l),this}normalizeFast(){const f=(3-(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w))/2;return 0===f?(this.x=0,this.y=0,this.z=0,this.w=0):(this.x*=f,this.y*=f,this.z*=f,this.w*=f),this}vmult(v,target=new Vec3){const x=v.x,y=v.y,z=v.z,qx=this.x,qy=this.y,qz=this.z,qw=this.w,ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;return target.x=ix*qw+iw*-qx+iy*-qz-iz*-qy,target.y=iy*qw+iw*-qy+iz*-qx-ix*-qz,target.z=iz*qw+iw*-qz+ix*-qy-iy*-qx,target}copy(quat){return this.x=quat.x,this.y=quat.y,this.z=quat.z,this.w=quat.w,this}toEuler(target,order="YZX"){let heading,attitude,bank;const x=this.x,y=this.y,z=this.z,w=this.w;switch(order){case"YZX":const test=x*y+z*w;if(test>.499&&(heading=2*Math.atan2(x,w),attitude=Math.PI/2,bank=0),test<-.499&&(heading=-2*Math.atan2(x,w),attitude=-Math.PI/2,bank=0),void 0===heading){const sqx=x*x,sqy=y*y,sqz=z*z;heading=Math.atan2(2*y*w-2*x*z,1-2*sqy-2*sqz),attitude=Math.asin(2*test),bank=Math.atan2(2*x*w-2*y*z,1-2*sqx-2*sqz)}break;default:throw new Error("Euler order "+order+" not supported yet.")}target.y=heading,target.z=attitude,target.x=bank}setFromEuler(x,y,z,order="XYZ"){const c1=Math.cos(x/2),c2=Math.cos(y/2),c3=Math.cos(z/2),s1=Math.sin(x/2),s2=Math.sin(y/2),s3=Math.sin(z/2);return"XYZ"===order?(this.x=s1*c2*c3+c1*s2*s3,this.y=c1*s2*c3-s1*c2*s3,this.z=c1*c2*s3+s1*s2*c3,this.w=c1*c2*c3-s1*s2*s3):"YXZ"===order?(this.x=s1*c2*c3+c1*s2*s3,this.y=c1*s2*c3-s1*c2*s3,this.z=c1*c2*s3-s1*s2*c3,this.w=c1*c2*c3+s1*s2*s3):"ZXY"===order?(this.x=s1*c2*c3-c1*s2*s3,this.y=c1*s2*c3+s1*c2*s3,this.z=c1*c2*s3+s1*s2*c3,this.w=c1*c2*c3-s1*s2*s3):"ZYX"===order?(this.x=s1*c2*c3-c1*s2*s3,this.y=c1*s2*c3+s1*c2*s3,this.z=c1*c2*s3-s1*s2*c3,this.w=c1*c2*c3+s1*s2*s3):"YZX"===order?(this.x=s1*c2*c3+c1*s2*s3,this.y=c1*s2*c3+s1*c2*s3,this.z=c1*c2*s3-s1*s2*c3,this.w=c1*c2*c3-s1*s2*s3):"XZY"===order&&(this.x=s1*c2*c3-c1*s2*s3,this.y=c1*s2*c3-s1*c2*s3,this.z=c1*c2*s3+s1*s2*c3,this.w=c1*c2*c3+s1*s2*s3),this}clone(){return new Quaternion(this.x,this.y,this.z,this.w)}slerp(toQuat,t,target=new Quaternion){const ax=this.x,ay=this.y,az=this.z,aw=this.w;let omega,cosom,sinom,scale0,scale1,bx=toQuat.x,by=toQuat.y,bz=toQuat.z,bw=toQuat.w;return(cosom=ax*bx+ay*by+az*bz+aw*bw)<0&&(cosom=-cosom,bx=-bx,by=-by,bz=-bz,bw=-bw),1-cosom>1e-6?(omega=Math.acos(cosom),sinom=Math.sin(omega),scale0=Math.sin((1-t)*omega)/sinom,scale1=Math.sin(t*omega)/sinom):(scale0=1-t,scale1=t),target.x=scale0*ax+scale1*bx,target.y=scale0*ay+scale1*by,target.z=scale0*az+scale1*bz,target.w=scale0*aw+scale1*bw,target}integrate(angularVelocity,dt,angularFactor,target=new Quaternion){const ax=angularVelocity.x*angularFactor.x,ay=angularVelocity.y*angularFactor.y,az=angularVelocity.z*angularFactor.z,bx=this.x,by=this.y,bz=this.z,bw=this.w,half_dt=.5*dt;return target.x+=half_dt*(ax*bw+ay*bz-az*by),target.y+=half_dt*(ay*bw+az*bx-ax*bz),target.z+=half_dt*(az*bw+ax*by-ay*bx),target.w+=half_dt*(-ax*bx-ay*by-az*bz),target}}exports.Quaternion=Quaternion;const sfv_t1=new Vec3,sfv_t2=new Vec3,SHAPE_TYPES=exports.SHAPE_TYPES={SPHERE:1,PLANE:2,BOX:4,COMPOUND:8,CONVEXPOLYHEDRON:16,HEIGHTFIELD:32,PARTICLE:64,CYLINDER:128,TRIMESH:256};class Shape{constructor(options={}){this.id=Shape.idCounter++,this.type=options.type||0,this.boundingSphereRadius=0,this.collisionResponse=!options.collisionResponse||options.collisionResponse,this.collisionFilterGroup=void 0!==options.collisionFilterGroup?options.collisionFilterGroup:1,this.collisionFilterMask=void 0!==options.collisionFilterMask?options.collisionFilterMask:-1,this.material=options.material?options.material:null,this.body=null}updateBoundingSphereRadius(){throw"computeBoundingSphereRadius() not implemented for shape type "+this.type}volume(){throw"volume() not implemented for shape type "+this.type}calculateLocalInertia(mass,target){throw"calculateLocalInertia() not implemented for shape type "+this.type}calculateWorldAABB(pos,quat,min,max){throw"calculateWorldAABB() not implemented for shape type "+this.type}}exports.Shape=Shape,Shape.idCounter=0,Shape.types=SHAPE_TYPES;class Transform{constructor(options={}){this.position=new Vec3,this.quaternion=new Quaternion,options.position&&this.position.copy(options.position),options.quaternion&&this.quaternion.copy(options.quaternion)}pointToLocal(worldPoint,result){return Transform.pointToLocalFrame(this.position,this.quaternion,worldPoint,result)}pointToWorld(localPoint,result){return Transform.pointToWorldFrame(this.position,this.quaternion,localPoint,result)}vectorToWorldFrame(localVector,result=new Vec3){return this.quaternion.vmult(localVector,result),result}static pointToLocalFrame(position,quaternion,worldPoint,result=new Vec3){return worldPoint.vsub(position,result),quaternion.conjugate(tmpQuat),tmpQuat.vmult(result,result),result}static pointToWorldFrame(position,quaternion,localPoint,result=new Vec3){return quaternion.vmult(localPoint,result),result.vadd(position,result),result}static vectorToWorldFrame(quaternion,localVector,result=new Vec3){return quaternion.vmult(localVector,result),result}static vectorToLocalFrame(position,quaternion,worldVector,result=new Vec3){return quaternion.w*=-1,quaternion.vmult(worldVector,result),quaternion.w*=-1,result}}exports.Transform=Transform;const tmpQuat=new Quaternion;class ConvexPolyhedron extends Shape{constructor(props={}){const{vertices:vertices=[],faces:faces=[],normals:normals=[],axes:axes,boundingSphereRadius:boundingSphereRadius}=props;super({type:Shape.types.CONVEXPOLYHEDRON}),this.vertices=vertices,this.faces=faces,this.faceNormals=normals,0===this.faceNormals.length&&this.computeNormals(),boundingSphereRadius?this.boundingSphereRadius=boundingSphereRadius:this.updateBoundingSphereRadius(),this.worldVertices=[],this.worldVerticesNeedsUpdate=!0,this.worldFaceNormals=[],this.worldFaceNormalsNeedsUpdate=!0,this.uniqueAxes=axes?axes.slice():null,this.uniqueEdges=[],this.computeEdges()}computeEdges(){const faces=this.faces,vertices=this.vertices,edges=this.uniqueEdges;edges.length=0;const edge=new Vec3;for(let i=0;i!==faces.length;i++){const face=faces[i],numVertices=face.length;for(let j=0;j!==numVertices;j++){const k=(j+1)%numVertices;vertices[face[j]].vsub(vertices[face[k]],edge),edge.normalize();let found=!1;for(let p=0;p!==edges.length;p++)if(edges[p].almostEquals(edge)||edges[p].almostEquals(edge)){found=!0;break}found||edges.push(edge.clone())}}}computeNormals(){this.faceNormals.length=this.faces.length;for(let i=0;i<this.faces.length;i++){for(let j=0;j<this.faces[i].length;j++)if(!this.vertices[this.faces[i][j]])throw new Error("Vertex "+this.faces[i][j]+" not found!");const n=this.faceNormals[i]||new Vec3;this.getFaceNormal(i,n),n.negate(n),this.faceNormals[i]=n;const vertex=this.vertices[this.faces[i][0]];if(n.dot(vertex)<0){console.error(".faceNormals["+i+"] = Vec3("+n.toString()+") looks like it points into the shape? The vertices follow. Make sure they are ordered CCW around the normal, using the right hand rule.");for(let j=0;j<this.faces[i].length;j++)console.warn(".vertices["+this.faces[i][j]+"] = Vec3("+this.vertices[this.faces[i][j]].toString()+")")}}}getFaceNormal(i,target){const f=this.faces[i],va=this.vertices[f[0]],vb=this.vertices[f[1]],vc=this.vertices[f[2]];ConvexPolyhedron.computeNormal(va,vb,vc,target)}clipAgainstHull(posA,quatA,hullB,posB,quatB,separatingNormal,minDist,maxDist,result){const WorldNormal=new Vec3;let closestFaceB=-1,dmax=-Number.MAX_VALUE;for(let face=0;face<hullB.faces.length;face++){WorldNormal.copy(hullB.faceNormals[face]),quatB.vmult(WorldNormal,WorldNormal);const d=WorldNormal.dot(separatingNormal);d>dmax&&(dmax=d,closestFaceB=face)}const worldVertsB1=[];for(let i=0;i<hullB.faces[closestFaceB].length;i++){const b=hullB.vertices[hullB.faces[closestFaceB][i]],worldb=new Vec3;worldb.copy(b),quatB.vmult(worldb,worldb),posB.vadd(worldb,worldb),worldVertsB1.push(worldb)}closestFaceB>=0&&this.clipFaceAgainstHull(separatingNormal,posA,quatA,worldVertsB1,minDist,maxDist,result)}findSeparatingAxis(hullB,posA,quatA,posB,quatB,target,faceListA,faceListB){const faceANormalWS3=new Vec3,Worldnormal1=new Vec3,deltaC=new Vec3,worldEdge0=new Vec3,worldEdge1=new Vec3,Cross=new Vec3;let dmin=Number.MAX_VALUE;const hullA=this;if(hullA.uniqueAxes)for(let i=0;i!==hullA.uniqueAxes.length;i++){quatA.vmult(hullA.uniqueAxes[i],faceANormalWS3);const d=hullA.testSepAxis(faceANormalWS3,hullB,posA,quatA,posB,quatB);if(!1===d)return!1;d<dmin&&(dmin=d,target.copy(faceANormalWS3))}else{const numFacesA=faceListA?faceListA.length:hullA.faces.length;for(let i=0;i<numFacesA;i++){const fi=faceListA?faceListA[i]:i;faceANormalWS3.copy(hullA.faceNormals[fi]),quatA.vmult(faceANormalWS3,faceANormalWS3);const d=hullA.testSepAxis(faceANormalWS3,hullB,posA,quatA,posB,quatB);if(!1===d)return!1;d<dmin&&(dmin=d,target.copy(faceANormalWS3))}}if(hullB.uniqueAxes)for(let i=0;i!==hullB.uniqueAxes.length;i++){quatB.vmult(hullB.uniqueAxes[i],Worldnormal1);const d=hullA.testSepAxis(Worldnormal1,hullB,posA,quatA,posB,quatB);if(!1===d)return!1;d<dmin&&(dmin=d,target.copy(Worldnormal1))}else{const numFacesB=faceListB?faceListB.length:hullB.faces.length;for(let i=0;i<numFacesB;i++){const fi=faceListB?faceListB[i]:i;Worldnormal1.copy(hullB.faceNormals[fi]),quatB.vmult(Worldnormal1,Worldnormal1);const d=hullA.testSepAxis(Worldnormal1,hullB,posA,quatA,posB,quatB);if(!1===d)return!1;d<dmin&&(dmin=d,target.copy(Worldnormal1))}}for(let e0=0;e0!==hullA.uniqueEdges.length;e0++){quatA.vmult(hullA.uniqueEdges[e0],worldEdge0);for(let e1=0;e1!==hullB.uniqueEdges.length;e1++)if(quatB.vmult(hullB.uniqueEdges[e1],worldEdge1),worldEdge0.cross(worldEdge1,Cross),!Cross.almostZero()){Cross.normalize();const dist=hullA.testSepAxis(Cross,hullB,posA,quatA,posB,quatB);if(!1===dist)return!1;dist<dmin&&(dmin=dist,target.copy(Cross))}}return posB.vsub(posA,deltaC),deltaC.dot(target)>0&&target.negate(target),!0}testSepAxis(axis,hullB,posA,quatA,posB,quatB){ConvexPolyhedron.project(this,axis,posA,quatA,maxminA),ConvexPolyhedron.project(hullB,axis,posB,quatB,maxminB);const maxA=maxminA[0],minA=maxminA[1],maxB=maxminB[0],minB=maxminB[1];if(maxA<minB||maxB<minA)return!1;const d0=maxA-minB,d1=maxB-minA;return d0<d1?d0:d1}calculateLocalInertia(mass,target){const aabbmax=new Vec3,aabbmin=new Vec3;this.computeLocalAABB(aabbmin,aabbmax);const x=aabbmax.x-aabbmin.x,y=aabbmax.y-aabbmin.y,z=aabbmax.z-aabbmin.z;target.x=1/12*mass*(2*y*2*y+2*z*2*z),target.y=1/12*mass*(2*x*2*x+2*z*2*z),target.z=1/12*mass*(2*y*2*y+2*x*2*x)}getPlaneConstantOfFace(face_i){const f=this.faces[face_i],n=this.faceNormals[face_i],v=this.vertices[f[0]];return-n.dot(v)}clipFaceAgainstHull(separatingNormal,posA,quatA,worldVertsB1,minDist,maxDist,result){const faceANormalWS=new Vec3,edge0=new Vec3,WorldEdge0=new Vec3,worldPlaneAnormal1=new Vec3,planeNormalWS1=new Vec3,worldA1=new Vec3,localPlaneNormal=new Vec3,planeNormalWS=new Vec3,hullA=this,pVtxIn=worldVertsB1,pVtxOut=[];let closestFaceA=-1,dmin=Number.MAX_VALUE;for(let face=0;face<hullA.faces.length;face++){faceANormalWS.copy(hullA.faceNormals[face]),quatA.vmult(faceANormalWS,faceANormalWS);const d=faceANormalWS.dot(separatingNormal);d<dmin&&(dmin=d,closestFaceA=face)}if(closestFaceA<0)return;const polyA=hullA.faces[closestFaceA];polyA.connectedFaces=[];for(let i=0;i<hullA.faces.length;i++)for(let j=0;j<hullA.faces[i].length;j++)-1!==polyA.indexOf(hullA.faces[i][j])&&i!==closestFaceA&&-1===polyA.connectedFaces.indexOf(i)&&polyA.connectedFaces.push(i);const numVerticesA=polyA.length;for(let i=0;i<numVerticesA;i++){const a=hullA.vertices[polyA[i]],b=hullA.vertices[polyA[(i+1)%numVerticesA]];a.vsub(b,edge0),WorldEdge0.copy(edge0),quatA.vmult(WorldEdge0,WorldEdge0),posA.vadd(WorldEdge0,WorldEdge0),worldPlaneAnormal1.copy(this.faceNormals[closestFaceA]),quatA.vmult(worldPlaneAnormal1,worldPlaneAnormal1),posA.vadd(worldPlaneAnormal1,worldPlaneAnormal1),WorldEdge0.cross(worldPlaneAnormal1,planeNormalWS1),planeNormalWS1.negate(planeNormalWS1),worldA1.copy(a),quatA.vmult(worldA1,worldA1),posA.vadd(worldA1,worldA1);const otherFace=polyA.connectedFaces[i];localPlaneNormal.copy(this.faceNormals[otherFace]);const localPlaneEq=this.getPlaneConstantOfFace(otherFace);planeNormalWS.copy(localPlaneNormal),quatA.vmult(planeNormalWS,planeNormalWS);const planeEqWS=localPlaneEq-planeNormalWS.dot(posA);for(this.clipFaceAgainstPlane(pVtxIn,pVtxOut,planeNormalWS,planeEqWS);pVtxIn.length;)pVtxIn.shift();for(;pVtxOut.length;)pVtxIn.push(pVtxOut.shift())}localPlaneNormal.copy(this.faceNormals[closestFaceA]);const localPlaneEq=this.getPlaneConstantOfFace(closestFaceA);planeNormalWS.copy(localPlaneNormal),quatA.vmult(planeNormalWS,planeNormalWS);const planeEqWS=localPlaneEq-planeNormalWS.dot(posA);for(let i=0;i<pVtxIn.length;i++){let depth=planeNormalWS.dot(pVtxIn[i])+planeEqWS;if(depth<=minDist&&(console.log("clamped: depth="+depth+" to minDist="+minDist),depth=minDist),depth<=maxDist){const point=pVtxIn[i];if(depth<=1e-6){const p={point:point,normal:planeNormalWS,depth:depth};result.push(p)}}}}clipFaceAgainstPlane(inVertices,outVertices,planeNormal,planeConstant){let n_dot_first,n_dot_last;const numVerts=inVertices.length;if(numVerts<2)return outVertices;let firstVertex=inVertices[inVertices.length-1],lastVertex=inVertices[0];n_dot_first=planeNormal.dot(firstVertex)+planeConstant;for(let vi=0;vi<numVerts;vi++){if(lastVertex=inVertices[vi],n_dot_last=planeNormal.dot(lastVertex)+planeConstant,n_dot_first<0)if(n_dot_last<0){const newv=new Vec3;newv.copy(lastVertex),outVertices.push(newv)}else{const newv=new Vec3;firstVertex.lerp(lastVertex,n_dot_first/(n_dot_first-n_dot_last),newv),outVertices.push(newv)}else if(n_dot_last<0){const newv=new Vec3;firstVertex.lerp(lastVertex,n_dot_first/(n_dot_first-n_dot_last),newv),outVertices.push(newv),outVertices.push(lastVertex)}firstVertex=lastVertex,n_dot_first=n_dot_last}return outVertices}computeWorldVertices(position,quat){for(;this.worldVertices.length<this.vertices.length;)this.worldVertices.push(new Vec3);const verts=this.vertices,worldVerts=this.worldVertices;for(let i=0;i!==this.vertices.length;i++)quat.vmult(verts[i],worldVerts[i]),position.vadd(worldVerts[i],worldVerts[i]);this.worldVerticesNeedsUpdate=!1}computeLocalAABB(aabbmin,aabbmax){const vertices=this.vertices;aabbmin.set(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE),aabbmax.set(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE);for(let i=0;i<this.vertices.length;i++){const v=vertices[i];v.x<aabbmin.x?aabbmin.x=v.x:v.x>aabbmax.x&&(aabbmax.x=v.x),v.y<aabbmin.y?aabbmin.y=v.y:v.y>aabbmax.y&&(aabbmax.y=v.y),v.z<aabbmin.z?aabbmin.z=v.z:v.z>aabbmax.z&&(aabbmax.z=v.z)}}computeWorldFaceNormals(quat){const N=this.faceNormals.length;for(;this.worldFaceNormals.length<N;)this.worldFaceNormals.push(new Vec3);const normals=this.faceNormals,worldNormals=this.worldFaceNormals;for(let i=0;i!==N;i++)quat.vmult(normals[i],worldNormals[i]);this.worldFaceNormalsNeedsUpdate=!1}updateBoundingSphereRadius(){let max2=0;const verts=this.vertices;for(let i=0;i!==verts.length;i++){const norm2=verts[i].lengthSquared();norm2>max2&&(max2=norm2)}this.boundingSphereRadius=Math.sqrt(max2)}calculateWorldAABB(pos,quat,min,max){const verts=this.vertices;let minx,miny,minz,maxx,maxy,maxz,tempWorldVertex=new Vec3;for(let i=0;i<verts.length;i++){tempWorldVertex.copy(verts[i]),quat.vmult(tempWorldVertex,tempWorldVertex),pos.vadd(tempWorldVertex,tempWorldVertex);const v=tempWorldVertex;(void 0===minx||v.x<minx)&&(minx=v.x),(void 0===maxx||v.x>maxx)&&(maxx=v.x),(void 0===miny||v.y<miny)&&(miny=v.y),(void 0===maxy||v.y>maxy)&&(maxy=v.y),(void 0===minz||v.z<minz)&&(minz=v.z),(void 0===maxz||v.z>maxz)&&(maxz=v.z)}min.set(minx,miny,minz),max.set(maxx,maxy,maxz)}volume(){return 4*Math.PI*this.boundingSphereRadius/3}getAveragePointLocal(target=new Vec3){const verts=this.vertices;for(let i=0;i<verts.length;i++)target.vadd(verts[i],target);return target.scale(1/verts.length,target),target}transformAllPoints(offset,quat){const n=this.vertices.length,verts=this.vertices;if(quat){for(let i=0;i<n;i++){const v=verts[i];quat.vmult(v,v)}for(let i=0;i<this.faceNormals.length;i++){const v=this.faceNormals[i];quat.vmult(v,v)}}if(offset)for(let i=0;i<n;i++){const v=verts[i];v.vadd(offset,v)}}pointIsInside(p){const verts=this.vertices,faces=this.faces,normals=this.faceNormals,pointInside=new Vec3;this.getAveragePointLocal(pointInside);for(let i=0;i<this.faces.length;i++){let n=normals[i];const v=verts[faces[i][0]],vToP=new Vec3;p.vsub(v,vToP);const r1=n.dot(vToP),vToPointInside=new Vec3;pointInside.vsub(v,vToPointInside);const r2=n.dot(vToPointInside);if(r1<0&&r2>0||r1>0&&r2<0)return!1}return-1}}exports.ConvexPolyhedron=ConvexPolyhedron,ConvexPolyhedron.computeNormal=((va,vb,vc,target)=>{const cb=new Vec3,ab=new Vec3;vb.vsub(va,ab),vc.vsub(vb,cb),cb.cross(ab,target),target.isZero()||target.normalize()});const maxminA=[],maxminB=[];ConvexPolyhedron.project=((shape,axis,pos,quat,result)=>{const n=shape.vertices.length,localAxis=new Vec3;let max=0,min=0;const localOrigin=new Vec3,vs=shape.vertices;localOrigin.setZero(),Transform.vectorToLocalFrame(pos,quat,axis,localAxis),Transform.pointToLocalFrame(pos,quat,localOrigin,localOrigin);const add=localOrigin.dot(localAxis);min=max=vs[0].dot(localAxis);for(let i=1;i<n;i++){const val=vs[i].dot(localAxis);val>max&&(max=val),val<min&&(min=val)}if((min-=add)>(max-=add)){const temp=min;min=max,max=temp}result[0]=max,result[1]=min});class Box extends Shape{constructor(halfExtents){super({type:Shape.types.BOX}),this.halfExtents=halfExtents,this.convexPolyhedronRepresentation=null,this.updateConvexPolyhedronRepresentation(),this.updateBoundingSphereRadius()}updateConvexPolyhedronRepresentation(){const sx=this.halfExtents.x,sy=this.halfExtents.y,sz=this.halfExtents.z,V=Vec3,vertices=[new V(-sx,-sy,-sz),new V(sx,-sy,-sz),new V(sx,sy,-sz),new V(-sx,sy,-sz),new V(-sx,-sy,sz),new V(sx,-sy,sz),new V(sx,sy,sz),new V(-sx,sy,sz)],axes=[new V(0,0,1),new V(0,1,0),new V(1,0,0)],h=new ConvexPolyhedron({vertices:vertices,faces:[[3,2,1,0],[4,5,6,7],[5,4,0,1],[2,3,7,6],[0,4,7,3],[1,2,6,5]],axes:axes});this.convexPolyhedronRepresentation=h,h.material=this.material}calculateLocalInertia(mass,target=new Vec3){return Box.calculateInertia(this.halfExtents,mass,target),target}getSideNormals(sixTargetVectors,quat){const sides=sixTargetVectors,ex=this.halfExtents;if(sides[0].set(ex.x,0,0),sides[1].set(0,ex.y,0),sides[2].set(0,0,ex.z),sides[3].set(-ex.x,0,0),sides[4].set(0,-ex.y,0),sides[5].set(0,0,-ex.z),void 0!==quat)for(let i=0;i!==sides.length;i++)quat.vmult(sides[i],sides[i]);return sides}volume(){return 8*this.halfExtents.x*this.halfExtents.y*this.halfExtents.z}updateBoundingSphereRadius(){this.boundingSphereRadius=this.halfExtents.length()}forEachWorldCorner(pos,quat,callback){const e=this.halfExtents,corners=[[e.x,e.y,e.z],[-e.x,e.y,e.z],[-e.x,-e.y,e.z],[-e.x,-e.y,-e.z],[e.x,-e.y,-e.z],[e.x,e.y,-e.z],[-e.x,e.y,-e.z],[e.x,-e.y,e.z]];for(let i=0;i<corners.length;i++)worldCornerTempPos.set(corners[i][0],corners[i][1],corners[i][2]),quat.vmult(worldCornerTempPos,worldCornerTempPos),pos.vadd(worldCornerTempPos,worldCornerTempPos),callback(worldCornerTempPos.x,worldCornerTempPos.y,worldCornerTempPos.z)}calculateWorldAABB(pos,quat,min,max){const e=this.halfExtents;worldCornersTemp[0].set(e.x,e.y,e.z),worldCornersTemp[1].set(-e.x,e.y,e.z),worldCornersTemp[2].set(-e.x,-e.y,e.z),worldCornersTemp[3].set(-e.x,-e.y,-e.z),worldCornersTemp[4].set(e.x,-e.y,-e.z),worldCornersTemp[5].set(e.x,e.y,-e.z),worldCornersTemp[6].set(-e.x,e.y,-e.z),worldCornersTemp[7].set(e.x,-e.y,e.z);const wc=worldCornersTemp[0];quat.vmult(wc,wc),pos.vadd(wc,wc),max.copy(wc),min.copy(wc);for(let i=1;i<8;i++){const wc=worldCornersTemp[i];quat.vmult(wc,wc),pos.vadd(wc,wc);const x=wc.x,y=wc.y,z=wc.z;x>max.x&&(max.x=x),y>max.y&&(max.y=y),z>max.z&&(max.z=z),x<min.x&&(min.x=x),y<min.y&&(min.y=y),z<min.z&&(min.z=z)}}}exports.Box=Box,Box.calculateInertia=((halfExtents,mass,target)=>{const e=halfExtents;target.x=1/12*mass*(2*e.y*2*e.y+2*e.z*2*e.z),target.y=1/12*mass*(2*e.x*2*e.x+2*e.z*2*e.z),target.z=1/12*mass*(2*e.y*2*e.y+2*e.x*2*e.x)});const worldCornerTempPos=new Vec3,worldCornersTemp=[new Vec3,new Vec3,new Vec3,new Vec3,new Vec3,new Vec3,new Vec3,new Vec3],BODY_SLEEP_STATES=(exports.BODY_TYPES={DYNAMIC:1,STATIC:2,KINEMATIC:4},exports.BODY_SLEEP_STATES={AWAKE:0,SLEEPY:1,SLEEPING:2});class Body extends EventTarget{constructor(options={}){super(),this.id=Body.idCounter++,this.index=-1,this.world=null,this.preStep=null,this.postStep=null,this.vlambda=new Vec3,this.collisionFilterGroup="number"==typeof options.collisionFilterGroup?options.collisionFilterGroup:1,this.collisionFilterMask="number"==typeof options.collisionFilterMask?options.collisionFilterMask:-1,this.collisionResponse="boolean"!=typeof options.collisionResponse||options.collisionResponse,this.position=new Vec3,this.previousPosition=new Vec3,this.interpolatedPosition=new Vec3,this.initPosition=new Vec3,options.position&&(this.position.copy(options.position),this.previousPosition.copy(options.position),this.interpolatedPosition.copy(options.position),this.initPosition.copy(options.position)),this.velocity=new Vec3,options.velocity&&this.velocity.copy(options.velocity),this.initVelocity=new Vec3