import o0 from "./o0.js" module.exports = { Filter: class { constructor() { this.stableAcceleration = null; this.maxrecordCount = 999999; this.frame = []; this.frameHit = []; //打击后的n帧 for (var i = 0; i < 200; ++i) { var o = new Object(); o.time = new Date().getTime(); o.timeGap = 20; o.acc = new o0.Vector2(0, 0); o.gyr = new o0.Vector2(0, 0); o.accFixed = 0; o.accSlope = 0; o.pos = new o0.Vector2(0, 0); o.predict = new o0.Vector2(0, 0); o.shake = 0; o.shakeFixed = 1; o.shakeSlope = 0; o.reliable = 1; o.speed = new o0.Vector2(0, 0); o.hit = 0; this.frame.push(o); //this.frameHit.push(o); } this.frameSwing = this.frame[0]; //this.frame = 0; this.force = new o0.Vector2(0, 0); this.forceChanged = 0; this.momentum = 999999; this.momentunTime = 0; this.momentunSeek = 0.1; this.momentunPunch = false; this.punchCount = 0; this.leftRight = false; this.forceRecord = []; for (var i = 0; i < 1; ++i) { this.forceRecord.push(new o0.Vector2(0, 0)); } /** */ this.angle = 0; this.quitHitCount = 0; } Update(vector3, timeGap, gyr, callback) { if (this.stableAcceleration == null) { this.stableAcceleration = vector3; this.recordCount = 1; } else { this.recordCount += 1; if (this.recordCount > this.maxrecordCount) { this.recordCount = this.maxrecordCount; } let recordCount = this.recordCount; this.stableAcceleration = this.stableAcceleration.multiply((recordCount - 1) / recordCount).plus(vector3.multiply( 1 / recordCount)); } //++this.frame; var newForce = vector3.minus(this.stableAcceleration); var newFrame = new Object(); newFrame.time = new Date().getTime(); newFrame.timeGap = timeGap; newFrame.acc = new o0.Vector2(newForce.x, newForce.z); newFrame.gyr = new o0.Vector2(gyr.z, -gyr.x); let lastFrame = this.frame[this.frame.length - 1]; let last2Frame = this.frame[this.frame.length - 2]; let last3Frame = this.frame[this.frame.length - 3]; let last4Frame = this.frame[this.frame.length - 4]; let last5Frame = this.frame[this.frame.length - 5]; ////////////////////////////////////////////////////////////////////// newFrame.accFixed = newFrame.acc.length * 100; if (newFrame.accFixed < lastFrame.accFixed * 0.85) { newFrame.accFixed = lastFrame.accFixed * 0.85; } lastFrame.accFixed = Math.max(lastFrame.accFixed, Math.min(newFrame.accFixed, last2Frame.accFixed), Math.min( newFrame.accFixed, last3Frame.accFixed)); /////////////////////////////////////////////////////////////////////// //newFrame.pos = lastFrame.pos.plus(lastFrame.acc.plus(newFrame.acc).multiply(timeGap/60)).multiply(Math.max(1-timeGap/200,0)); newFrame.pos = lastFrame.pos.plus(newFrame.acc.multiply(timeGap / 30)).multiply(Math.max(1 - timeGap / 1000, 0)); //////////////////////////////////////////// var accSlpoe1 = (newFrame.accFixed - lastFrame.accFixed); var accSlpoe2 = (newFrame.accFixed - last2Frame.accFixed); var accSlpoe3 = (newFrame.accFixed - last3Frame.accFixed); //newFrame.accSlope = accSlpoe1; //newFrame.accSlope = Math.min(accSlpoe1,accSlpoe2); //newFrame.accSlope = Math.min(accSlpoe1,accSlpoe2,accSlpoe3); newFrame.accSlope = Math.max(newFrame.accFixed - lastFrame.accFixed, 0); /* if(newFrame.accSlope > 8){ newFrame.accSlope = 1; }else if(newFrame.accSlope <= 8){ newFrame.accSlope = 0; }/** */ ///////////////////////////////////////////////// var lastI = this.frame.length - 1; var t2 = this.frame[lastI - 1].timeGap; var t3 = this.frame[lastI].timeGap + t2; var t4 = newFrame.timeGap + t3; /*newFrame.predict = new o0.Vector2( new o0.QuadraticEquation(0,this.frame[lastI-2].acc.x,t2,this.frame[lastI-1].acc.x,t3,this.frame[lastI].acc.x).y(t4), new o0.QuadraticEquation(0,this.frame[lastI-2].acc.y,t2,this.frame[lastI-1].acc.y,t3,this.frame[lastI].acc.y).y(t4));/** */ /* newFrame.predict = new o0.Vector2( new o0.QuadraticEquation(0,this.frame[lastI-2].pos.x,t2,this.frame[lastI-1].pos.x,t3,this.frame[lastI].pos.x).y(t4), new o0.QuadraticEquation(0,this.frame[lastI-2].pos.y,t2,this.frame[lastI-1].pos.y,t3,this.frame[lastI].pos.y).y(t4));/** */ newFrame.predict = new o0.Vector2( new o0.QuadraticEquation(0, this.frame[lastI - 2].pos.x, t2, this.frame[lastI - 1].pos.x, t3, this.frame[lastI] .pos.x).y(t4), new o0.QuadraticEquation(0, this.frame[lastI - 2].pos.y, t2, this.frame[lastI - 1].pos.y, t3, this.frame[lastI] .pos.y).y(t4)); /** */ //console.log(newFrame.pos); ////////////////////////////////////////// //newFrame.shake = o0.distance2(newFrame.predict,newFrame.pos) * 500; //console.log(newFrame.pos.minus(lastFrame.pos).mod.angle(newFrame.predict.minus(lastFrame.pos).mod)); //newFrame.shake = o0.distance2(newFrame.predict,newFrame.acc) * 100; newFrame.shake = o0.distance2(newFrame.predict, newFrame.pos) * 100; //newFrame.shake = o0.distance2(newFrame.predict,lastFrame.pos) * newFrame.acc.length / timeGap * 2000; if (isNaN(newFrame.shake)) { newFrame.shake = 0.0; } /** */ //newFrame.shake = Math.pow(o0.distance2(newFrame.predict,newFrame.pos) * newFrame.acc.length / timeGap,0.5) * 500; /////////////////////////////下面的代码有优化空间 //newFrame.shakeFixed = lastFrame.shakeFixed * 0.9; //newFrame.shakeFixed = lastFrame.shakeFixed*(1.0+newFrame.shake)*0.9; //newFrame.shakeFixed = Math.pow(lastFrame.shakeFixed*(1.0+newFrame.shake),0.5)+1; //console.log(newFrame.shakeFixed+1); //newFrame.shakeFixed = newFrame.shake; newFrame.shakeFixed = lastFrame.shakeFixed * 0.85; if (newFrame.shake > newFrame.shakeFixed) { newFrame.shakeFixed = newFrame.shake; } /* */ lastFrame.shakeFixed = Math.max(lastFrame.shakeFixed, Math.min(newFrame.shakeFixed, last2Frame.shakeFixed), Math.min( newFrame.shakeFixed, last3Frame.shakeFixed)); //////////////////////////////////////////////////////////////// /* var shakeSlpoe1 = (newFrame.shakeFixed-lastFrame.shakeFixed); var shakeSlpoe2 = (newFrame.shakeFixed-last2Frame.shakeFixed); var shakeSlpoe3 = (newFrame.shakeFixed-last3Frame.shakeFixed); //newFrame.accSlope = accSlpoe1; //newFrame.accSlope = Math.min(accSlpoe1,accSlpoe2); newFrame.shakeSlope = Math.min(shakeSlpoe1,shakeSlpoe2,shakeSlpoe3); newFrame.shakeSlope = Math.max(newFrame.shakeSlope,0);/** */ newFrame.shakeSlope = Math.max(newFrame.shakeFixed - lastFrame.shakeFixed, 0); /* if(newFrame.shakeSlope > 40){ newFrame.shakeSlope = 1; }else{ newFrame.shakeSlope = 0; }/** */ ////////////////////////////////////////////// /* var slopeChange = newFrame.shakeFixed - lastFrame.shakeFixed; if(slopeChange < 0){ newFrame.slope = (lastFrame.slope + (newFrame.shakeFixed - lastFrame.shakeFixed) / timeGap * 100) * 0.8; }else{ newFrame.slope = (lastFrame.slope + (newFrame.shakeFixed - lastFrame.shakeFixed) / timeGap * 20) * 0.8; } if(newFrame.slope<0){ newFrame.slope = 0; }/** */ /////////////////////////////下面的代码有很大优化空间 if (lastFrame.hit == 0 && last2Frame.hit == 0 && last3Frame.hit == 0 && last4Frame.hit == 0 && last5Frame.hit == 0 && (newFrame.accSlope >= 15 || lastFrame.accSlope >= 20) && (newFrame.shakeSlope >= 20 || lastFrame.shakeSlope >= 40)) { newFrame.hit = newFrame.shake; this.frameHit = []; //this.frameSwing = last2Frame; for (var i = this.frame.length - 3; i >= 1; --i) { let io = this.frame[i]; let pio = this.frame[i - 1]; if (io.accFixed * 0.85 <= pio.accFixed && io.accFixed >= pio.accFixed * 0.85) { this.frameSwing = io; } } } else { newFrame.hit = 0; } /* if(lastFrame.hit == 0 && this.frame[this.frame.length-2].hit == 0 && this.frame[this.frame.length-3].hit == 0 && newFrame.shakeFixed > 150 && newFrame.shakeFixed > lastFrame.shakeFixed * 2){ newFrame.hit = newFrame.shakeFixed; }else{ newFrame.hit = 0; }/** */ /////////////力量大小 if (lastFrame.hit != 0) { lastFrame.hit = lastFrame.hit + newFrame.shake; } else if (last2Frame.hit != 0) { last2Frame.hit = last2Frame.hit + newFrame.shake; } else if (last3Frame.hit != 0) { last3Frame.hit = last3Frame.hit + newFrame.shake; } else if (last4Frame.hit != 0) { last4Frame.hit = last4Frame.hit + newFrame.shake; } else if (last5Frame.hit != 0) { last5Frame.hit = last5Frame.hit + newFrame.shake; this.getDirection(last5Frame.hit, callback); } /** */ //newFrame.shake = o0.distance2(newFrame.predict,newFrame.pos) * o0.distance2(lastFrame.pos,newFrame.pos); ////////////////////////////////////////////////////////////////////////////////// newFrame.reliable = Math.pow((Math.PI / 2 - Math.atan(newFrame.shakeFixed / 10000)) / (Math.PI / 2), 2000); let lastFrameAddSpeed = lastFrame.acc.multiply(lastFrame.timeGap / 20).multiply(lastFrame.reliable); let newFrameAddSpeed = newFrame.acc.multiply(newFrame.timeGap / 20).multiply(newFrame.reliable); newFrame.speed = lastFrame.speed.multiply(0.8); var lastFrameAngle = newFrame.speed.angle(lastFrameAddSpeed); if (isNaN(lastFrameAngle)) { lastFrameAngle = 180.0; } //newFrame.speed = newFrame.speed.plus(lastFrameAddSpeed.multiply(Math.max(1,lastFrameAngle/60.0 - 1))); //newFrame.speed = newFrame.speed.multiply(1).plus(lastFrameAddSpeed.multiply(Math.max(1,lastFrameAngle/60.0 - 1))); newFrame.speed = newFrame.speed.multiply(1 - lastFrameAngle / 360.0).plus(lastFrameAddSpeed.multiply(Math.max(1, lastFrameAngle / 60.0 - 1))); var newFrameAngle = newFrame.speed.angle(newFrameAddSpeed); if (isNaN(newFrameAngle)) { newFrameAngle = 180.0; } //newFrame.speed = newFrame.speed.plus(newFrameAddSpeed.multiply(Math.min(1,newFrameAngle/60.0-1))); newFrame.speed = newFrame.speed.multiply(1 - newFrameAngle / 360.0).plus(newFrameAddSpeed.multiply(Math.max(1, newFrameAngle / 60.0 - 1))); ////////////////////// this.frame.shift(); this.frame.push(newFrame); if (this.frameHit.length <= 10) { var o = new Object(); o.time = newFrame.time; o.timeGap = newFrame.timeGap; o.acc = newFrame.acc; o.gyr = newFrame.gyr; let frameHitLength = this.frameHit.length + 1; let lastFrameHit = this.frameHit[this.frameHit.length - 1]; if (frameHitLength == 1) { o.allShakeLength = newFrame.shakeFixed; } else { o.allShakeLength = lastFrameHit.allShakeLength + newFrame.shakeFixed; } o.accFixed = o.acc.multiply(Math.pow(Math.max(0, 1 - newFrame.shakeFixed * frameHitLength / o.allShakeLength), 5) * 20); //数字越大越忽略历史数据 if (frameHitLength == 1) { o.pos = o.accFixed.multiply(o.timeGap / 60); } else { o.pos = lastFrameHit.pos.plus(lastFrameHit.accFixed.plus(o.accFixed).multiply(o.timeGap / 60)); } this.frameHit.push(o); } var vectorChanged = newForce.minus(this.force); var forceLength = this.force.length; var ForceChanged = newForce.length - forceLength; this.force = newForce; var currentLeftRight; if (Math.abs(newForce.x + newForce.z) > Math.abs(newForce.x - newForce.z)) { currentLeftRight = Math.abs(newForce.x + newForce.z); } else { currentLeftRight = -Math.abs(newForce.x - newForce.z); } this.forceRecord.shift(); this.forceRecord.push(newForce); if (this.forceChanged > 0 && ForceChanged < 0) { // && forceLength > 0.1 //&& this.momentum * Math.pow(0.9,(new Date().getTime()-this.momentunTime)/1) < forceLength){ /*console.log(forceLength.toFixed(2)); if( forceLength > 0.1 && forceLength >= this.momentum * 1.5){ console.log(this.frame+" "+forceLength); }/** */ if (forceLength > 0.1 && this.momentum != 999999) { if (!this.momentunPunch) { //等待击打 if (this.momentunSeek > this.momentum) { this.momentunSeek = this.momentum; } else { if (this.momentunSeek < this.momentum * 0.8 - 0.1) { this.momentunPunch = !this.momentunPunch; this.punchCount++; //this.leftRight = (newForce.x+this.force.x) < 0; /* var largestForce = new o0.Vector3(0,0,0) for(var i = 0;i Math.abs(largestForce.x - largestForce.z)){ currentLeftRight = Math.abs(largestForce.x + largestForce.z); }else{ currentLeftRight = -Math.abs(largestForce.x - largestForce.z); }/** */ this.leftRight = currentLeftRight < 0 ? "Right" : "Left"; this.angle = new o0.Vector2(newForce.x, newForce.z).mod.angle(new o0.Vector2(0, 1)); if (this.angle > 90) { this.angle = 180 - this.angle; } if (currentLeftRight > 0) { this.angle = -this.angle; } /** */ //this.leftRight = (largestChange.x > 0 && largestChange.z > 0) || (largestChange.x < 0 && largestChange.z < 0); /* */ //console.log(this.momentum); } } } else { //打完了 if (this.momentunSeek < this.momentum) { this.momentunSeek = this.momentum; } else if (this.momentunSeek > this.momentum * 1.2 + 0.1) { this.momentunPunch = !this.momentunPunch; } } } this.momentum = forceLength; this.momentunTime = new Date().getTime(); } this.forceChanged = ForceChanged; //console.log(vector3.x); return [new o0.Vector3(newForce), currentLeftRight, this.momentum]; } test() { return "123123131"; } getDirection(hitValue, callback) { var direction = new o0.Vector2(0, 0); var directionDistance = 0; for (var fi = 1; fi < this.frameHit.length - 1; ++fi) { for (var li = fi + 1; li < this.frameHit.length; ++li) { let firstGyr = this.frameHit[fi].gyr; let lastGyr = this.frameHit[li].gyr; let newDirectionDistance = o0.distance2(firstGyr, lastGyr); if (directionDistance < newDirectionDistance) { directionDistance = newDirectionDistance; direction = lastGyr.minus(firstGyr); } } } let curAngle = new o0.Vector2(direction.x, direction.y).mod.angle(new o0.Vector2(0, 1)); let directionPunch = "all", name = "击中", ename = "hit"; let curAngleCeil = Math.ceil(curAngle); //已坐标 (0,1) 向量为参考 if (direction.y < 0) { //相反方向击打 //正方向 if (curAngleCeil > 150) { directionPunch = "straightPunch"; name = "负向的直拳"; ename = "back-straight"; } else if (direction.x > 0) { directionPunch = "rightPunch"; name = "负向的右拳"; ename = "back-right"; } else if (direction.x < 0) { directionPunch = "leftPunch"; name = "负向的左拳"; ename = "back-left"; } } else { // y 大于零 手柄正方向击打 if (curAngleCeil < 30) { directionPunch = "straightPunch"; name = "正向的直拳"; ename = "front-straight"; } else if (direction.x < 0) { directionPunch = "rightPunch"; name = "正向的右拳"; ename = "front-right"; } else if (direction.x > 0) { directionPunch = "leftPunch"; name = "正向的左拳"; ename = "front-left"; } } this.quitHitCount++; if (callback) { let temp = { type: 'hit', hit: hitValue / 5, hitCount: this.quitHitCount, direction: directionPunch, directionVect: { 'x': direction.x, 'y': direction.y }, angle: curAngleCeil, name: name, ename: ename } callback(temp); } } } };