diff options
| author | Gubolin <gubolin@fantasymail.de> | 2014-08-13 13:35:14 +0200 |
|---|---|---|
| committer | Gubolin <gubolin@fantasymail.de> | 2014-08-13 13:35:14 +0200 |
| commit | 6560149027b29c4e2844e3bd52e8731379fb1b91 (patch) | |
| tree | 9af881c5563669705ee10187962149d2230fee7b | |
| parent | e55c5e035a46c2a3353ce3f21bca3daf6b3fee6c (diff) | |
| download | snap-6560149027b29c4e2844e3bd52e8731379fb1b91.tar.gz snap-6560149027b29c4e2844e3bd52e8731379fb1b91.zip | |
add motion reporters
| -rw-r--r-- | blocks.js | 1 | ||||
| -rw-r--r-- | objects.js | 16 | ||||
| -rw-r--r-- | threads.js | 80 |
3 files changed, 78 insertions, 19 deletions
@@ -6571,7 +6571,6 @@ InputSlotMorph.prototype.messagesReceivedMenu = function () { InputSlotMorph.prototype.collidablesMenu = function () { var dict = { 'mouse-pointer' : ['mouse-pointer'], - 'camera motion' : ['camera motion'], edge : ['edge'], 'pen trails' : ['pen trails'] }, @@ -785,6 +785,18 @@ SpriteMorph.prototype.initBlocks = function () { category: 'sensing', spec: 'color %clr is touching %clr ?' }, + reportCameraMotion: { + only: SpriteMorph, + type: 'predicate', + category: 'sensing', + spec: 'camera motion at my position?' + }, + reportCameraDirection: { + only: SpriteMorph, + type: 'reporter', + category: 'sensing', + spec: 'camera motion direction' + }, colorFiltered: { dev: true, type: 'reporter', @@ -1868,6 +1880,9 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push(block('reportTouchingColor')); blocks.push(block('reportColorIsTouchingColor')); blocks.push('-'); + blocks.push(block('reportCameraMotion')); + blocks.push(block('reportCameraDirection')); + blocks.push('-'); blocks.push(block('doAsk')); blocks.push(watcherToggle('getLastAnswer')); blocks.push(block('getLastAnswer')); @@ -4269,6 +4284,7 @@ StageMorph.prototype.init = function (globals) { this.lastAnswer = ''; // last user input, do not persist this.activeSounds = []; // do not persist this.lastCameraCanvas = null; + this.lastCameraMotion = new Point(0, 0); this.trailsCanvas = null; this.isThreadSafe = false; @@ -2355,24 +2355,6 @@ Process.prototype.objectTouchingObject = function (thisObj, name) { } else { stage = thisObj.parentThatIsA(StageMorph); if (stage) { - if (this.inputOption(name) === 'camera motion') { - var motionCanvas = this.getCameraMotion(); - - var x = thisObj.xPosition() + 210, y = 170 - thisObj.yPosition(); - // ouch! hardcoded ^ ^ - var motionData = motionCanvas.getContext('2d').getImageData( - x, y, thisObj.width(), thisObj.height()); - var i = 0, average = 0; - while (i < (motionData.data.length * 0.25)) { - average += (motionData.data[i*4] + motionData.data[i*4+1] - + motionData.data[i*4+2]) / 3; - ++i; - } - average = Math.round(average / (motionData.data.length * 0.25)); - if (average > 10) { - return true; - } - } if (this.inputOption(name) === 'edge' && !stage.bounds.containsRectangle(thisObj.bounds)) { return true; @@ -2442,6 +2424,62 @@ Process.prototype.reportColorIsTouchingColor = function (color1, color2) { return false; }; +Process.prototype.reportCameraMotion = function () { + var thisObj = this.blockReceiver(); + var motionCanvas = this.getCameraMotion(); + + var x = thisObj.xPosition() + 210, y = 170 - thisObj.yPosition(); + // ouch! hardcoded ^ ^ + var motionData = motionCanvas.getContext('2d').getImageData( + x, y, thisObj.width(), thisObj.height()); + var i = 0, average = 0; + while (i < (motionData.data.length * 0.25)) { + average += (motionData.data[i*4] + + motionData.data[i*4+1] + motionData.data[i*4+2]) / 3; + ++i; + } + average = Math.round(average / (motionData.data.length * 0.25)); + if (average > 10) { + return true; + } else { + return false; + } +}; + +Process.prototype.reportCameraDirection = function () { + var stage = this.homeContext.receiver.parentThatIsA(StageMorph); + var motionCanvas = this.getCameraMotion(); + var canv = document.createElement('canvas'), + ctx = canv.getContext('2d'); + var data = motionCanvas.getContext('2d') + .getImageData(0, 0, motionCanvas.width, motionCanvas.height); + // scale, saves some time + canv.width = motionCanvas.width / 10; + canv.height = motionCanvas.height / 10; + ctx.drawImage(motionCanvas, 0, 0, canv.width, canv.height); + var yval = 0, xval = 0, cnt = 0; + var motion, imageData = ctx.getImageData(0, 0, canv.width, canv.height); + // find the geometric center of the moving object + for (var j = 0; j < canv.height; j++) { + for (var k = 0; k < canv.width; k++) { + motion = imageData.data[(j*canv.width+k)*4]; + yval += j * motion; + xval += k * motion; + cnt += motion; + } + } + // calculate the angle between this center and the last one + var resultX = Math.round(xval / cnt / 1) * 1; + var resultY = Math.round(yval / cnt / 1) * 1; + var diff = (resultX + resultY) - + (stage.lastCameraMotion.x - stage.lastCameraMotion.y); + var deg = 0; + deg = degrees(Math.atan2(resultX - stage.lastCameraMotion.x, + stage.lastCameraMotion.y - resultY)); + stage.lastCameraMotion = new Point(resultX, resultY); + return deg; +}; + Process.prototype.reportDistanceTo = function (name) { var thisObj = this.blockReceiver(), thatObj, @@ -2753,6 +2791,12 @@ Process.prototype.doPlayNoteForSecs = function (pitch, secs) { // Process camera streaming primitives Process.prototype.doStreamCamera = function () { + if ((Date.now() - this.context.startTime) < 3000) { + // 20 FPS is enough + this.pushContext('doYield'); + this.pushContext(); + return; + } var myself = this; var video = this.context.activeStream || null; |
