@zeainc/zea-kinematics
Version:
Kinematics extension for Zea Engine.
3 lines (2 loc) • 28.6 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@zeainc/zea-engine"),require("@zeainc/zea-ux")):"function"==typeof define&&define.amd?define(["exports","@zeainc/zea-engine","@zeainc/zea-ux"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).zeaKinematics={},t.zeaEngine,t.zeaUx)}(this,(function(t,e,s){"use strict";var a={name:"@zeainc/zea-kinematics",libraryName:"ZeaKinematics",fileName:"zea-kinematics",author:"Philip Taylor",description:"Kinematics extension for Zea Engine.",version:"4.0.4",license:"MIT",main:"dist/index.cjs.js",browser:"dist/index.esm.js",umd:"dist/index.umd.js","umd.min":"dist/index.umd.min.js",types:"dist/zea-kinematics.d.ts",files:["dist/"],keywords:["WebGL","ES6","Zea"],repository:{type:"git",url:"git+ssh://git@github.com:ZeaInc/zea-kinematics.git"},scripts:{build:"rollup -c","build:watch":"rollup -c -w",dev:"npm-run-all --parallel build:watch start:watch",dist:"yarn publish --access=public",docs:"cp CHANGELOG.md docs/ && adg --config adg.config.json","docs-w":"cp CHANGELOG.md docs/ && adg -w --config=adg.config.json","docs:serve":"docsify serve docs/",generate:"plop",prepare:"yarn run build",release:"standard-version",start:"es-dev-server --cors","start:watch":"es-dev-server --app-index testing-e2e/index.html --cors --open --watch","test:e2e":"percy exec cypress run --browser chrome --headless","test:e2e:watch":"percy exec cypress open"},devDependencies:{"@percy/cypress":"^2.3.2","@rollup/plugin-commonjs":"^21.0.1","@rollup/plugin-json":"^4.1.0","@zeainc/jsdocs2md":"^0.0.7","@zeainc/zea-engine":"^4","@zeainc/zea-ux":"4.6.0-caa887e",cypress:"^5.4.0","docsify-cli":"^4.4.1","es-dev-server":"^1.57.8",eslint:"^6.5.1","eslint-config-google":"^0.14.0","eslint-config-prettier":"^6.3.0","eslint-plugin-prettier":"^3.1.1","npm-run-all":"^4.1.5",plop:"^2.7.4",prettier:"^2.1.1",rollup:"^2.60.1","rollup-plugin-commonjs":"^10.1.0","rollup-plugin-dts":"^4.1.0","rollup-plugin-terser":"^7.0.2","rollup-plugin-node-resolve":"^5.2.0","rollup-plugin-typescript":"^1.0.1","standard-version":"^9.0.0","ts-node":"^10.4.0",typescript:"^4.5.4","worker-loader":"^2.0.0",yargs:"12.0.2"},dependencies:{}};class i extends e.StructParameter{constructor(t=""){super(t),this.stageParam=new e.NumberParameter("Stage",0),this.axisParam=new e.Vec3Parameter("Axis",new e.Vec3(1,0,0)),this.movementParam=new e.Vec2Parameter("MovementTiming",new e.Vec2(0,1),[new e.Vec2(0,0),new e.Vec2(1,1)]),this.multiplierParam=new e.NumberParameter("Multiplier",1),this.output=new e.XfoOperatorOutput("output",e.OperatorOutputMode.OP_READ_WRITE),this.addMember(this.stageParam),this.addMember(this.axisParam),this.addMember(this.movementParam),this.addMember(this.multiplierParam)}getStage(){return this.stageParam.getValue()}setStage(t){this.stageParam.setValue(t)}getOutput(){return this.output}evaluate(t,s,a,i,r,n,o,h){if(!this.output.isConnected())return;const u=this.stageParam.getValue(),l=this.movementParam.getValue();let m;if(r){let a=u/i;n&&(a-=.5),m=s*e.MathFunctions.linStep(l.x,l.y,Math.max(0,t-a))}else{let a=1-u/i;n&&(a-=.5),m=s*e.MathFunctions.linStep(l.x,l.y,t)*a}m+=a;let c=this.axisParam.getValue();const d=this.multiplierParam.getValue();let g=this.output.getValue();o&&(g=h.multiply(g),c=o.ori.rotateVec3(c)),g.tr.addInPlace(c.scale(m*d)),this.output.setClean(g)}toJSON(t){const e=super.toJSON(t);return e&&(e.output=this.output.toJSON(t)),e}fromJSON(t,e){super.fromJSON(t,e),t.output&&this.output.fromJSON(t.output,e)}}class r extends e.Operator{constructor(t){super(t),this.stagesParam=new e.NumberParameter("Stages",0),this.explodeParam=new e.NumberParameter("Explode",0,[0,1]),this.distParam=new e.NumberParameter("Dist",1),this.offsetParam=new e.NumberParameter("Offset",0),this.cascadeParam=new e.BooleanParameter("Cascade",!1),this.centeredParam=new e.BooleanParameter("Centered",!1),this.parentItemParam=new e.TreeItemParameter("RelativeTo"),this.itemsParam=new e.ListParameter("Parts",typeof i),this.addParameter(this.stagesParam),this.addParameter(this.explodeParam),this.addParameter(this.distParam),this.addParameter(this.offsetParam),this.addParameter(this.cascadeParam),this.addParameter(this.centeredParam),this.addParameter(this.parentItemParam),this.parentItemParam.on("valueChanged",(()=>{const t=this.parentItemParam.getValue();this.invParentSpace=t?t.getParameter("GlobalXfo").getValue().inverse():void 0})),this.parentItemParam.on("treeItemGlobalXfoChanged",(()=>{this.setDirty()})),this.addParameter(this.itemsParam),this.itemsParam.on("elementAdded",(t=>{if(t.index>0){const e=this.itemsParam.getElement(t.index-1).getStage();t.elem.setStage(e+1),this.stagesParam.setValue(e+2)}else this.stagesParam.setValue(1);t.elem.output=new e.XfoOperatorOutput("Part"+t.index,e.OperatorOutputMode.OP_READ_WRITE),this.addOutput(t.elem.getOutput()),this.setDirty()})),this.itemsParam.on("elementRemoved",(t=>{this.removeOutput(t.elem.getOutput())})),this.addParameter(this.itemsParam),this.localXfos=[]}addPart(){const t=new i;return this.itemsParam.addElement(t),t}evaluate(){const t=this.stagesParam.getValue(),e=this.explodeParam.getValue(),s=this.distParam.getValue(),a=this.offsetParam.getValue(),i=this.cascadeParam.getValue(),r=this.centeredParam.getValue(),n=this.parentItemParam.getValue();let o,h;n&&(o=n.getParameter("GlobalXfo").getValue(),h=this.invParentSpace.multiply(o));const u=this.itemsParam.getValue();for(let n=0;n<u.length;n++){u[n].evaluate(e,s,a,t,i,r,o,h)}}toJSON(t){return super.toJSON(t)}fromJSON(t,e){super.fromJSON(t,e)}}e.Registry.register("ExplodePartsOperator",r);class n extends e.StructParameter{constructor(t){super(t),this.__ratioParam=new e.NumberParameter("Ratio",1),this.__offsetParam=new e.NumberParameter("Offset",0),this.__axisParam=new e.Vec3Parameter("Axis",new e.Vec3(1,0,0)),this.addMember(this.__ratioParam),this.addMember(this.__offsetParam),this.addMember(this.__axisParam)}getOutput(){return this.__output}getRatio(){return this.__ratioParam.getValue()}getOffset(){return this.__offsetParam.getValue()}getAxis(){return this.__axisParam.getValue()}toJSON(t){const e=super.toJSON(t);return e&&(e.output=this.__output.toJSON(t)),e}fromJSON(t,e){super.fromJSON(t,e),t.output&&this.__output.fromJSON(t.output,e)}}class o extends e.Operator{constructor(t){super(t),this.__revolutionsParam=new e.NumberParameter("Revolutions",0),this.rpmParam=new e.NumberParameter("RPM",0),this.__gearsParam=new e.ListParameter("Gears",typeof n),this.addParameter(this.__revolutionsParam),this.addParameter(this.rpmParam),this.rpmParam.on("valueChanged",(()=>{const t=this.rpmParam.getValue();if(Math.abs(t)>0){if(!this.__timeoutId){const t=()=>{const e=this.rpmParam.getValue(),s=this.__revolutionsParam.getValue();this.__revolutionsParam.setValue(s+e*(1/3e3)),this.__timeoutId=setTimeout(t,20)};t()}}else clearTimeout(this.__timeoutId),this.__timeoutId=void 0})),this.addParameter(this.__gearsParam),this.__gearsParam.on("elementAdded",(t=>{t.elem.__output=new e.XfoOperatorOutput("Gear"+t.index,e.OperatorOutputMode.OP_READ_WRITE),this.addOutput(t.elem.getOutput())})),this.__gearsParam.on("elementRemoved",(t=>{this.removeOutput(t.index)})),this.__gears=[]}addGear(){const t=new n;return this.__gearsParam.addElement(t),t}evaluate(){const t=this.__revolutionsParam.getValue();this.__gearsParam.getValue().forEach(((s,a)=>{const i=this.getOutputByIndex(a);if(!i.isConnected())return;const r=t*s.getRatio()+s.getOffset(),n=new e.Quat;n.setFromAxisAndAngle(s.getAxis(),r*Math.PI*2);const o=i.getValue();o.ori=n.multiply(o.ori),i.setClean(o)}))}detach(){super.detach(),this.__timeoutId&&(clearTimeout(this.__timeoutId),this.__timeoutId=null)}reattach(){super.reattach(),this.getParameter("RPM").emit("valueChanged",{})}destroy(){this.__timeoutId&&(clearTimeout(this.__timeoutId),this.__timeoutId=null)}}e.Registry.register("GearsOperator",o);class h extends e.Operator{constructor(t){super(t),this.weightParam=new e.NumberParameter("Weight",1),this.axisParam=new e.MultiChoiceParameter("Axis",0,["+X Axis","-X Axis","+Y Axis","-Y Axis","+Z Axis","-Z Axis"]),this.stretchParam=new e.NumberParameter("Stretch",0),this.initialDistParam=new e.NumberParameter("Initial Dist",1),this.targetInput=new e.XfoOperatorInput("Target"),this.xfoInputOutput=new e.XfoOperatorOutput("InputOutput",e.OperatorOutputMode.OP_READ_WRITE),this.addParameter(this.weightParam),this.addParameter(this.axisParam),this.addParameter(this.stretchParam),this.addParameter(this.initialDistParam),this.addInput(this.targetInput),this.addOutput(this.xfoInputOutput)}resetStretchRefDist(){const t=this.targetInput.getValue(),e=this.getOutputByIndex(0).getValue(),s=t.tr.subtract(e.tr).length();this.initialDistParam.value=s}evaluate(){const t=this.weightParam.value,s=this.axisParam.value,a=this.targetInput.getValue(),i=this.getOutputByIndex(0),r=i.getValue(),n=a.tr.subtract(r.tr),o=n.length();if(o<1e-6)return;let h;switch(n.scaleInPlace(1/o),s){case 0:h=r.ori.getXaxis();break;case 1:h=r.ori.getXaxis().negate();break;case 2:h=r.ori.getYaxis();break;case 3:h=r.ori.getYaxis().negate();break;case 4:h=r.ori.getZaxis();break;case 5:h=r.ori.getZaxis().negate()}let u=new e.Quat;u.setFrom2Vectors(h,n),u.alignWith(new e.Quat),t<1&&(u=(new e.Quat).lerp(u,t)),r.ori=u.multiply(r.ori);const l=this.stretchParam.value;if(l>0){const t=1+(o/this.initialDistParam.value-1)*l;switch(s){case 0:case 1:r.sc.x=t;break;case 2:case 3:r.sc.y=t;break;case 4:case 5:r.sc.z=t}}i.setClean(r)}}e.Registry.register("AimOperator",h);class u extends e.Operator{constructor(t){super(t),this.axisParam=new e.MultiChoiceParameter("Axis",0,["+X Axis","-X Axis","+Y Axis","-Y Axis","+Z Axis","-Z Axis"]),this.ramXfoOutput=new e.XfoOperatorOutput("Ram",e.OperatorOutputMode.OP_READ_WRITE),this.pistonXfoOutput=new e.XfoOperatorOutput("Piston",e.OperatorOutputMode.OP_READ_WRITE),this.addParameter(this.axisParam),this.addOutput(this.ramXfoOutput),this.addOutput(this.pistonXfoOutput)}evaluate(){const t=this.getOutputByIndex(0),s=this.getOutputByIndex(1),a=t.getValue(),i=s.getValue(),r=this.axisParam.value,n=i.tr.subtract(a.tr);n.normalizeInPlace();const o=new e.Quat,h=new e.Quat;switch(r){case 0:o.setFrom2Vectors(a.ori.getXaxis(),n),h.setFrom2Vectors(i.ori.getXaxis().negate(),n);break;case 1:o.setFrom2Vectors(a.ori.getXaxis().negate(),n),h.setFrom2Vectors(i.ori.getXaxis(),n);break;case 2:o.setFrom2Vectors(a.ori.getYaxis(),n),h.setFrom2Vectors(i.ori.getYaxis().negate(),n);break;case 3:o.setFrom2Vectors(a.ori.getYaxis().negate(),n),h.setFrom2Vectors(i.ori.getYaxis(),n);break;case 4:o.setFrom2Vectors(a.ori.getZaxis(),n),h.setFrom2Vectors(i.ori.getZaxis().negate(),n);break;case 5:o.setFrom2Vectors(a.ori.getZaxis().negate(),n),h.setFrom2Vectors(i.ori.getZaxis(),n)}a.ori=o.multiply(a.ori),i.ori=h.multiply(i.ori),t.setClean(a),s.setClean(i)}}e.Registry.register("RamAndPistonOperator",u);class l extends e.Operator{constructor(t){super(t),this.targetXfoInput=new e.XfoOperatorInput("Target"),this.joint0XfoOutput=new e.XfoOperatorOutput("Joint0",e.OperatorOutputMode.OP_READ_WRITE),this.joint1XfoOutput=new e.XfoOperatorOutput("Joint1",e.OperatorOutputMode.OP_READ_WRITE),this.addInput(this.targetXfoInput),this.addOutput(this.joint0XfoOutput),this.addOutput(this.joint1XfoOutput),this.align=new e.Quat,this.enabled=!1}enable(){const t=this.targetXfoInput.getValue(),e=this.joint0XfoOutput.getValue(),s=this.joint1XfoOutput.getValue();this.joint1Offset=e.inverse().multiply(s).tr,this.joint1TargetOffset=s.inverse().multiply(t).tr,this.joint1TargetOffset.normalizeInPlace(),this.joint0Length=s.tr.distanceTo(e.tr),this.joint1Length=t.tr.distanceTo(s.tr),this.setDirty(),this.enabled=!0}evaluate(){const t=this.getInput("Target").getValue(),e=this.joint0XfoOutput,s=this.joint1XfoOutput,a=e.getValue(),i=s.getValue(),r=t.tr.subtract(a.tr),n=r.length(),o=a.ori.rotateVec3(this.joint1Offset),h=this.joint0Length,u=n,l=this.joint1Length,m=Math.acos((h*h+u*u-l*l)/(2*h*u));o.normalizeInPlace(),r.normalizeInPlace();const c=r.cross(o),d=r.angleTo(o);c.normalizeInPlace(),this.align.setFromAxisAndAngle(c,m-d),a.ori=this.align.multiply(a.ori),i.tr=a.transformVec3(this.joint1Offset);const g=t.tr.subtract(i.tr);g.normalizeInPlace(),this.align.setFrom2Vectors(i.ori.rotateVec3(this.joint1TargetOffset),g),i.ori=this.align.multiply(i.ori),e.setClean(a),s.setClean(i)}}e.Registry.register("TriangleIKSolver",l);const m=new e.Vec3(1,0,0),c=new e.Vec3(0,1,0),d=new e.Vec3(0,0,1),g=new e.Xfo,p=new e.Quat;class y{constructor(t,s=0,a,i,r){this.index=t,this.axisId=s,this.limits=[e.MathFunctions.degToRad(a[0]),e.MathFunctions.degToRad(a[1])],this.xfo=i.value,this.backPropagationWeight=0,this.align=new e.Quat,this.debugTree=new e.TreeItem("IKJoint"+t),r.addChild(this.debugTree),this.debugLines={}}addDebugSegment(t,s,a){this.debugLines[t]||(this.debugLines[t]=((t,s)=>{const a=new e.Lines,i=a.getVertexAttribute("positions"),r=new e.LinesMaterial("debug");r.baseColorParam.setValue(new e.Color(s)),r.getParameter("Overlay").setValue(1);const n=new e.GeomItem("Pointer",a,r);t.addChild(n);let o=0,h=0;return{addDebugSegment:(t,e)=>{const s=h,r=h+1;o++,h+=2,a.getNumVertices()<h&&a.setNumVertices(h),a.getNumSegments()<o&&a.setNumSegments(o),a.setSegmentVertexIndices(o-1,s,r),i.setValue(s,t),i.setValue(r,e)},doneFrame:()=>{a.emit("geomDataTopologyChanged"),o=0,h=0}}})(this.debugTree,t)),this.debugLines[t].addDebugSegment(s,a)}init(t,e,s){switch(this.localXfo=t.inverse().multiply(this.xfo),this.bindLocalXfo=this.localXfo.clone(),this.backPropagationWeight=e/(s-1),this.axisId){case 0:this.axis=m;break;case 1:this.axis=c;break;case 2:this.axis=d}}backPropagateOrientation(t,e,s,a){if(s==a.length-1&&(this.xfo.ori=e.ori.clone()),this.backPropagationWeight>0){const e=a[s-1],i=this.xfo.ori.rotateVec3(this.axis),r=(s>0?e.xfo:t).ori.rotateVec3(this.axis);if(this.align.setFrom2Vectors(i,r),1==this.backPropagationWeight)e.xfo.ori=this.align.conjugate().multiply(e.xfo.ori),e.xfo.ori.normalizeInPlace();else{const t=this.align.lerp(p,this.backPropagationWeight).conjugate();e.xfo.ori=t.multiply(e.xfo.ori),this.xfo.ori=this.align.lerp(p,1-this.backPropagationWeight).multiply(this.xfo.ori)}}else{const e=this.xfo.ori.rotateVec3(this.axis),i=(s>0?a[s-1].xfo:t).ori.rotateVec3(this.axis);this.align.setFrom2Vectors(e,i),this.xfo.ori=this.align.multiply(this.xfo.ori)}}forwardPropagateAlignment(t,s,a,i){{const t=s.tr.subtract(this.xfo.tr),e=i[i.length-1].xfo.tr.subtract(this.xfo.tr);e.length()>1e-4&&t.length()>1e-4&&(e.normalizeInPlace(),t.normalizeInPlace(),this.align.setFrom2Vectors(e,t),this.xfo.ori=this.align.multiply(this.xfo.ori))}this.xfo.ori.normalizeInPlace();{const e=this.xfo.ori.rotateVec3(this.axis),s=(a>0?i[a-1].xfo:t).ori.rotateVec3(this.axis);this.align.setFrom2Vectors(e,s),this.xfo.ori=this.align.multiply(this.xfo.ori)}{const s=(a>0?i[a-1].xfo:t).ori.inverse().multiply(this.xfo.ori);let r=s.w<1?s.getAngle():0;const n=new e.Vec3(s.x,s.y,s.x);if(this.axis.dot(n)>0&&(r=-r),r<this.limits[0]||r>this.limits[1]){const t=r<this.limits[0]?this.limits[0]-r:this.limits[1]-r;this.align.setFromAxisAndAngle(this.axis,-t),this.xfo.ori=this.xfo.ori.multiply(this.align)}}{let t=this.xfo;for(let e=a+1;e<i.length;e++){const s=i[e];s.xfo.ori=t.ori.multiply(s.localXfo.ori),s.xfo.tr=t.transformVec3(s.localXfo.tr),t=s.xfo}}}setClean(){for(let t in this.debugLines)this.debugLines[t].doneFrame();this.output.setClean(this.xfo)}}class f extends e.Operator{constructor(t){super(t),this.iterationsParam=new e.NumberParameter("Iterations",5),this.baseXfoInput=new e.XfoOperatorInput("Base"),this.targetXfoInput=new e.XfoOperatorInput("Target"),this.addParameter(this.iterationsParam),this.addInput(this.baseXfoInput),this.addInput(this.targetXfoInput),this.joints=[],this.enabled=!1,this.debugTree=new e.TreeItem("IKSolver-debug")}addJoint(t,s=0,a=[-180,180]){const i=new y(this.joints.length,s,a,t,this.debugTree),r=this.addOutput(new e.XfoOperatorOutput("Joint"+this.joints.length));return r.setParam(t),i.output=r,this.joints.push(i),i}enable(){const t=this.getInput("Base").isConnected()?this.getInput("Base").getValue():g;this.joints.forEach(((e,s)=>{const a=s>0?this.joints[s-1].xfo:t;e.init(a,s,this.joints.length)})),this.enabled=!0,this.setDirty()}evaluate(){const t=this.joints.length;if(this.enabled){const e=this.getInput("Target").getValue(),s=this.getInput("Base").isConnected()?this.getInput("Base").getValue():g,a=this.getParameter("Iterations").getValue();for(let i=0;i<a;i++){for(let a=t-1;a>=0;a--){this.joints[a].backPropagateOrientation(s,e,a,this.joints)}{let e=this.joints[0].xfo;for(let s=1;s<t;s++){const t=this.joints[s];t.localXfo.ori=e.ori.inverse().multiply(t.xfo.ori),t.xfo.ori=e.ori.multiply(t.localXfo.ori),t.xfo.tr=e.transformVec3(t.localXfo.tr),e=t.xfo}}for(let a=0;a<t;a++){this.joints[a].forwardPropagateAlignment(s,e,a,this.joints)}}}for(let e=0;e<t;e++)this.joints[e].setClean()}}e.Registry.register("IKSolver",f);class x extends e.Operator{constructor(t){super(t),this.timeInput=new e.NumberOperatorInput("Time"),this.attachedXfoOutput=new e.XfoOperatorOutput("Attached",e.OperatorOutputMode.OP_READ_WRITE),this.addInput(this.timeInput),this.addOutput(this.attachedXfoOutput),this.attachTargets=[],this.attachId=-1}addAttachTarget(t,s){const a=this.addInput(new e.XfoOperatorInput("Target"+this.getNumInputs()));a.setParam(t),this.attachTargets.push({input:a,time:s,offsetXfo:void 0})}getAttachTarget(t){return this.getInputByIndex(t+1)}findTarget(t){if(0==this.attachTargets.length||t<=this.attachTargets[0].time)return-1;const e=this.attachTargets.length;if(t>=this.attachTargets[e-1].time)return e-1;for(let s=1;s<e;s++){if(this.attachTargets[s].time>t)return s-1}}evaluate(){const t=this.getInput("Time").getValue(),e=this.getOutputByIndex(0);let s=e.getValue();const a=this.findTarget(t);if(-1!=a){const t=this.getAttachTarget(a).getValue(),e=this.attachTargets[a];if(a!=this.attachId){if(!e.offsetXfo)if(-1==this.attachId)e.offsetXfo=t.inverse().multiply(s);else{const s=this.getAttachTarget(this.attachId).getValue(),a=this.attachTargets[this.attachId].offsetXfo,i=t.inverse().multiply(s.multiply(a));e.offsetXfo=i}this.attachId=a}s=t.multiply(e.offsetXfo)}e.setClean(s)}}e.Registry.register("AttachmentConstraint",x);class P{constructor(t){this.index=t}}class O extends e.EventEmitter{constructor(t,e){super(),this.name=t,this.owner=e,this.keys=[],this.__sampleCache={},this.__currChange=null,this.__secondaryChange=null,this.__secondaryChangeTime=-1}getName(){return this.name}getOwner(){return this.owner}setOwner(t){this.owner=t}getPath(){return[...this.owner.getPath(),name]}getNumKeys(){return this.keys.length}getKeyTime(t){return this.keys[t].time}getKeyValue(t){return this.keys[t].value}setKeyValue(t,e){this.keys[t].value=e,this.emit("keyChanged",new P(t))}setKeyTimeAndValue(t,e,s){this.keys[t].time=e,this.keys[t].value=s,this.emit("keyChanged",new P(t))}getTimeRange(){if(0==this.keys.length)return new e.Vec2(Number.NaN,Number.NaN);const t=this.keys.length;return new e.Vec2(this.keys[0].time,this.keys[t-1].time)}addKey(t,e){let s;const a=this.keys.length;if(0==this.keys.length||t<this.keys[0].time)this.keys.splice(0,0,{time:t,value:e}),s=0;else if(t>this.keys[a-1].time)this.keys.push({time:t,value:e}),s=a;else for(let i=1;i<a;i++){if(this.keys[i].time>t){this.keys.splice(i,0,{time:t,value:e}),s=i;break}}return this.emit("keyAdded",new P(s)),s}updateKey(t,e){this.keys[t].value=e,this.emit("keyUpdated",new P(t))}removeKey(t){this.keys.splice(t,1),this.emit("keyRemoved",new P(t))}findKeyAndLerp(t){if(0==this.keys.length)return{keyIndex:-1,lerp:0};if(t<=this.keys[0].time)return{keyIndex:0,lerp:0};const e=this.keys.length;if(t>=this.keys[e-1].time)return{keyIndex:e-1,lerp:0};for(let s=1;s<e;s++){const e=this.keys[s];if(t<e.time){const a=this.keys[s-1],i=e.time-a.time;return{keyIndex:s-1,lerp:(t-a.time)/i}}}}evaluate(t){this.findKeyAndLerp(t)}setValue(t,e){const s=this.findKeyAndLerp(t);s.lerp>0?this.addKey(t,e):this.setKeyValue(s.keyIndex,e)}toJSON(t){const s={};return s.name=this.name,s.type=e.Registry.getClassName(Object.getPrototypeOf(this).constructor),s.keys=this.keys.map((t=>({time:t.time,value:t.value.toJSON?t.value.toJSON():t.value}))),s}fromJSON(t,e){this.__name=t.name,this.keys=t.keys.map((t=>this.loadKeyJSON(t))),this.emit("loaded")}loadKeyJSON(t){return{time:t.time,value:t.value}}}class k extends O{constructor(t){super(t)}evaluate(t){const s=this.findKeyAndLerp(t),a=this.keys[s.keyIndex].value;if(s.lerp>0){const t=this.keys[s.keyIndex+1].value,i=a.tr.lerp(t.tr,s.lerp),r=a.ori.lerp(t.ori,s.lerp);return new e.Xfo(i,r)}return a}loadKeyJSON(t){const s={time:t.time,value:new e.Xfo};return s.value.fromJSON(t.value),s}}e.Registry.register("XfoTrack",k);class V extends s.Change{constructor(t,e,s){super(`Add Key to ${t?t.getName():"track"}`),null!=t&&null!=e&&null!=s?(this.track=t,this.time=e,this.value=s,this.index=t.addKey(this.time,this.value)):super()}update(t){this.value=t,this.track.setKeyValue(this.index,this.value),this.emit("updated",{value:this.value})}emit(t,e){throw new Error("Method not implemented.")}undo(){this.track.removeKey(this.index)}redo(){this.track.addKey(this.time,this.value)}toJSON(t){const e={name:this.name,trackPath:this.track.getPath(),time:this.time};return null!=this.value&&(this.value.toJSON?e.value=this.value.toJSON():e.value=this.value),e}fromJSON(t,e){const s=e.appData.scene.getRoot().resolvePath(t.trackPath,1);if(!(s&&s instanceof O))return void console.warn("resolvePath is unable to resolve",t.trackPath);this.name=`Add Key to ${s.getName()}`,this.track=s;const a=this.track.loadKeyJSON(t);this.time=a.time,this.value=a.value,this.index=this.track.addKey(a.time,a.value)}changeFromJSON(t){this.track&&t.value&&(this.value=t.value,this.track.setKeyValue(this.index,this.value))}}s.UndoRedoManager.registerChange("AddKeyChange",V);class w extends s.Change{constructor(t,e,s,a){super(),null!=t&&null!=e&&null!=s?(this.track=t,this.index=e,this.prevValue=this.track.getKeyValue(this.index),this.newValue=s,null!=a?(this.newTime=a,this.track.setKeyTimeAndValue(this.index,this.newTime,this.newValue)):(this.newTime=this.track.getKeyTime(this.index),this.track.setKeyValue(this.index,this.newValue))):super()}update(t,e){this.newValue=t,null!=e?(this.newTime=e,this.track.setKeyTimeAndValue(this.index,this.newTime,this.newValue)):this.track.setKeyValue(this.index,this.newValue),this.emit("updated",{newValue:this.newValue.toJSON?this.newValue.toJSON():this.newValue,newTime:this.newTime})}undo(){this.track.setKeyValue(this.index,this.prevValue)}redo(){this.track.setKeyValue(this.index,this.newValue)}toJSON(t){return{name:this.name,trackPath:this.track.getPath(),newTime:this.newTime,newValue:this.newValue}}fromJSON(t,e){const s=e.appData.scene.getRoot().resolvePath(t.trackPath,1);if(!(s&&s instanceof O))return void console.warn("resolvePath is unable to resolve",t.trackPath);this.name=`Add Key to ${s.getName()}`,this.track=s;const a=this.track.loadKeyJSON(t);this.index=a.index,this.newTime=a.time,this.newValue=a.newValue,this.track.setKeyTimeAndValue(this.index,this.newTime,this.newValue)}changeFromJSON(t){if(!this.track)return;const e=this.track.loadKeyJSON(t);this.newTime=e.time,this.newValue=e.newValue,this.track.setKeyTimeAndValue(this.index,this.newTime,this.newValue)}}s.UndoRedoManager.registerChange("KeyChange",w);class v extends e.Operator{constructor(t,s){super(t),this.timeNumberOutput=new e.NumberOperatorInput("Time"),this.xfoOutput=new e.XfoOperatorOutput("Output",e.OperatorOutputMode.OP_WRITE),this.track=s;const a=()=>{this.setDirty()};this.track.on("keyAdded",a),this.track.on("keyRemoved",a),this.track.on("keyChanged",a),this.addInput(this.timeNumberOutput),this.addOutput(this.xfoOutput),this.__initialValue=null,this.__currChange=null,this.__secondaryChange=null,this.__secondaryChangeTime=-1,this.getOutput("Output").on("paramSet",(()=>{this.__initialValue=this.getOutput("Output").getValue()}))}backPropagateValue(t){const e=this.getInput("Time").getValue(),a=s.UndoRedoManager.getInstance().getCurrentChange();if(a&&a.addSecondaryChange)if(this.__currChange!=a||this.__secondaryChangeTime!=e){this.__currChange=a,this.__secondaryChangeTime=e;const s=this.track.findKeyAndLerp(e);-1==s.keyIndex||s.lerp>0||s.keyIndex==this.track.getNumKeys()-1&&this.track.getKeyTime(s.keyIndex)!=e?(this.__secondaryChange=new V(this.track,e,t),this.__currChange.addSecondaryChange(this.__secondaryChange)):(this.__secondaryChange=new w(this.track,s.keyIndex,t),this.__currChange.addSecondaryChange(this.__secondaryChange))}else this.__secondaryChange.update(t);else{const s=this.track.findKeyAndLerp(e);-1==s.keyIndex||s.lerp>0||s.keyIndex==this.track.getNumKeys()-1&&this.track.getKeyTime(s.keyIndex)!=e?this.track.addKey(e,t):this.track.setKeyValue(s.keyIndex,t)}return t}evaluate(){const t=this.getOutputByIndex(0);if(0==this.track.getNumKeys())t.isConnected()&&t.setClean(this.xfoOutput.getValue());else{const e=this.timeNumberOutput.getValue(),s=this.track.evaluate(e);t.setClean(s)}}}class I extends e.Operator{constructor(t,s){super(),this.keyLocalOutput=new e.XfoOperatorOutput("KeyLocal",e.OperatorOutputMode.OP_WRITE),this.addOutput(this.keyLocalOutput),this.track=t,this.keyIndex=s,this.track.on("keyChanged",(t=>{t.index==this.keyIndex&&this.setDirty()})),this.track.on("keyRemoved",(t=>{const{index:e}=t;this.keyIndex>=e&&this.setDirty()})),this.track.on("keyAdded",(t=>{const{index:e}=t;this.keyIndex>=e&&this.setDirty()}))}backPropagateValue(t){this.track.setKeyValue(this.keyIndex,t)}evaluate(){this.keyLocalOutput.setClean(this.track.getKeyValue(this.keyIndex))}}class _ extends e.GeomItem{constructor(t){super(t.getName()),this.track=t,this.getParameter("Geometry").setValue(new e.Lines);const a=new e.LinesMaterial("trackLine");a.baseColorParam.setValue(new e.Color(.3,.3,.3)),a.getParameter("Overlay").setValue(.5),this.getParameter("Material").setValue(a);const i=new e.PointsMaterial("trackDots");i.baseColorParam.setValue(new e.Color(.75,.75,.75)),i.getParameter("Overlay").setValue(.5),this.dotsItem=new e.GeomItem("dots",new e.Points,i),this.addChild(this.dotsItem),this.keyMat=new s.HandleMaterial("trackLine"),this.keyMat.getParameter("MaintainScreenSize").setValue(1),this.keyMat.getParameter("Overlay").setValue(.5),this.keyCube=new e.Cuboid(.004,.004,.004),this.keys=[],this.updatePath(),this.displayKeys(),this.track.on("keyAdded",(t=>{this.displayKeys(),this.updatePath()})),this.track.on("keyRemoved",(t=>{const e=this.keys.pop();this.removeChild(this.getChildIndex(e)),this.displayKeys(),this.updatePath()})),this.track.on("keyChanged",(t=>{this.updatePath()})),this.track.on("loaded",(()=>{this.updatePath(),this.displayKeys()}))}displayKeys(){const t=t=>{if(!this.keys[t]){const s=new e.GeomItem("key"+t,this.keyCube,this.keyMat);this.addChild(s);new I(this.track,t).keyLocalOutput.setParam(s.localXfoParam),this.keys.push(s)}},s=this.track.getNumKeys();for(let e=0;e<s;e++)t(e)}updatePath(t){const e=this.geomParam.value,s=this.dotsItem.geomParam.value,a=this.track.getTimeRange();if(Number.isNaN(a.x)||Number.isNaN(a.y))return;const i=Math.round((a.y-a.x)/50);if(0==i)return;e.setNumVertices(i+1),e.setNumSegments(i),s.setNumVertices(i+1);const r=e.getVertexAttribute("positions"),n=s.getVertexAttribute("positions");for(let t=0;t<=i;t++){t<i&&e.setSegmentVertexIndices(t,t,t+1);const s=a.x+(a.y-a.x)*(t/i),o=this.track.evaluate(s);r.setValue(t,o.tr),n.setValue(t,o.tr)}s.setBoundingBoxDirty(),s.emit("geomDataTopologyChanged",{}),e.setBoundingBoxDirty(),e.emit("geomDataTopologyChanged",{})}}class b extends s.Change{constructor(t,e){super(),this.track=t,this.index=e,this.time=t.getKeyTime(e),this.value=t.getKeyValue(e),this.track.removeKey(this.index)}undo(){this.track.addKey(this.time,this.value)}redo(){this.track.removeKey(this.index)}}s.UndoRedoManager.registerChange("RemoveKeyChange",b),e.libsRegistry?e.libsRegistry.registerLib(a):console.warn("The version of the Zea Engine that you're using doesn't support the libraries registry. Please upgrade to the latest Zea Engine version."),t.AddKeyChange=V,t.AimOperator=h,t.AttachmentConstraint=x,t.BaseTrack=O,t.ColorTrack=class extends O{constructor(t){super(t)}evaluate(t){const e=this.findKeyAndLerp(t),s=this.keys[e.keyIndex].value;if(e.lerp>0){const t=this.keys[e.keyIndex+1].value;return s.lerp(t,e.lerp)}return s}},t.ExplodePartsOperator=r,t.GearsOperator=o,t.IKSolver=f,t.IndexEvent=P,t.KeyChange=w,t.RamAndPistonOperator=u,t.RemoveKeyChange=b,t.TrackSampler=v,t.TriangleIKSolver=l,t.XfoTrack=k,t.XfoTrackDisplay=_,Object.defineProperty(t,"__esModule",{value:!0})}));
//# sourceMappingURL=index.umd.min.js.map