Skip to content

Commit

Permalink
Merge pull request #1028 from mzgoddard/motion-detect-4
Browse files Browse the repository at this point in the history
Motion detect 4
  • Loading branch information
thisandagain committed Apr 13, 2018
2 parents 8739a52 + 8ebd659 commit 3ac2922
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 64 deletions.
101 changes: 61 additions & 40 deletions src/extensions/scratch3_video_sensing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ const Video = require('../../io/video');

const VideoMotion = require('./library');

/**
* Sensor attribute video sensor block should report.
* @readonly
* @enum {string}
*/
const SensingAttribute = {
/** The amount of motion. */
MOTION: 'motion',

/** The direction of the motion. */
DIRECTION: 'direction'
};

/**
* Subject video sensor block should report for.
* @readonly
* @enum {string}
*/
const SensingSubject = {
/** The sensor traits of the whole stage. */
STAGE: 'Stage',

/** The senosr traits of the area overlapped by this sprite. */
SPRITE: 'this sprite'
};

/**
* States the video sensing activity can be set to.
* @readonly
Expand Down Expand Up @@ -176,59 +202,54 @@ class Scratch3VideoSensingBlocks {
return motionState;
}

static get SensingAttribute () {
return SensingAttribute;
}

/**
* An array of choices of whether a reporter should return the frame's
* motion amount or direction.
* @type {object[]} an array of objects.
* @param {string} name - the translatable name to display in the drums menu.
* @param {string} fileName - the name of the audio file containing the drum sound.
* @type {object[]} an array of objects
* @param {string} name - the translatable name to display in sensor
* attribute menu
* @param {string} value - the serializable value of the attribute
*/
get MOTION_DIRECTION_INFO () {
get ATTRIBUTE_INFO () {
return [
{
name: 'motion'
name: 'motion',
value: SensingAttribute.MOTION
},
{
name: 'direction'
name: 'direction',
value: SensingAttribute.DIRECTION
}
];
}

static get MOTION () {
return 1;
}

static get DIRECTION () {
return 2;
static get SensingSubject () {
return SensingSubject;
}

/**
* An array of info about each drum.
* @type {object[]} an array of objects.
* @param {string} name - the translatable name to display in the drums
* menu.
* @param {string} fileName - the name of the audio file containing the
* drum sound.
* An array of info about the subject choices.
* @type {object[]} an array of objects
* @param {string} name - the translatable name to display in the subject menu
* @param {string} value - the serializable value of the subject
*/
get STAGE_SPRITE_INFO () {
get SUBJECT_INFO () {
return [
{
name: 'stage'
name: 'stage',
value: SensingSubject.STAGE
},
{
name: 'sprite'
name: 'sprite',
value: SensingSubject.SPRITE
}
];
}

static get STAGE () {
return 1;
}

static get SPRITE () {
return 2;
}

/**
* States the video sensing activity can be set to.
* @readonly
Expand Down Expand Up @@ -272,17 +293,17 @@ class Scratch3VideoSensingBlocks {
{
opcode: 'videoOn',
blockType: BlockType.REPORTER,
text: 'video [MOTION_DIRECTION] on [STAGE_SPRITE]',
text: 'video [ATTRIBUTE] on [SUBJECT]',
arguments: {
MOTION_DIRECTION: {
ATTRIBUTE: {
type: ArgumentType.NUMBER,
menu: 'MOTION_DIRECTION',
defaultValue: Scratch3VideoSensingBlocks.MOTION
menu: 'ATTRIBUTE',
defaultValue: SensingAttribute.MOTION
},
STAGE_SPRITE: {
SUBJECT: {
type: ArgumentType.NUMBER,
menu: 'STAGE_SPRITE',
defaultValue: Scratch3VideoSensingBlocks.STAGE
menu: 'SUBJECT',
defaultValue: SensingSubject.STAGE
}
}
},
Expand Down Expand Up @@ -322,8 +343,8 @@ class Scratch3VideoSensingBlocks {
}
],
menus: {
MOTION_DIRECTION: this._buildMenu(this.MOTION_DIRECTION_INFO),
STAGE_SPRITE: this._buildMenu(this.STAGE_SPRITE_INFO),
ATTRIBUTE: this._buildMenu(this.ATTRIBUTE_INFO),
SUBJECT: this._buildMenu(this.SUBJECT_INFO),
VIDEO_STATE: this._buildMenu(this.VIDEO_STATE_INFO)
}
};
Expand Down Expand Up @@ -353,11 +374,11 @@ class Scratch3VideoSensingBlocks {
this.detect.analyzeFrame();

let state = this.detect;
if (Number(args.STAGE_SPRITE) === Scratch3VideoSensingBlocks.SPRITE) {
if (args.SUBJECT === SensingSubject.SPRITE) {
state = this._analyzeLocalMotion(util.target);
}

if (Number(args.MOTION_DIRECTION) === Scratch3VideoSensingBlocks.MOTION) {
if (args.ATTRIBUTE === SensingAttribute.MOTION) {
return state.motionAmount;
}
return state.motionDirection;
Expand Down
16 changes: 4 additions & 12 deletions src/serialization/sb2.js
Original file line number Diff line number Diff line change
Expand Up @@ -611,21 +611,13 @@ const parseBlock = function (sb2block, addBroadcastMsg, getVariableId, extension
if (shadowObscured) {
fieldValue = 1;
}
} else if (expectedArg.inputOp === 'videoSensing.menu.MOTION_DIRECTION') {
} else if (expectedArg.inputOp === 'videoSensing.menu.ATTRIBUTE') {
if (shadowObscured) {
fieldValue = 1;
} else if (fieldValue === 'motion') {
fieldValue = 1;
} else if (fieldValue === 'direction') {
fieldValue = 2;
fieldValue = 'motion';
}
} else if (expectedArg.inputOp === 'videoSensing.menu.STAGE_SPRITE') {
} else if (expectedArg.inputOp === 'videoSensing.menu.SUBJECT') {
if (shadowObscured) {
fieldValue = 2;
} else if (fieldValue === 'Stage') {
fieldValue = 1;
} else if (fieldValue === 'this sprite') {
fieldValue = 2;
fieldValue = 'this sprite';
}
} else if (expectedArg.inputOp === 'videoSensing.menu.VIDEO_STATE') {
if (shadowObscured) {
Expand Down
8 changes: 4 additions & 4 deletions src/serialization/sb2_specmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -614,13 +614,13 @@ const specMap = {
argMap: [
{
type: 'input',
inputOp: 'videoSensing.menu.MOTION_DIRECTION',
inputName: 'MOTION_DIRECTION'
inputOp: 'videoSensing.menu.ATTRIBUTE',
inputName: 'ATTRIBUTE'
},
{
type: 'input',
inputOp: 'videoSensing.menu.STAGE_SPRITE',
inputName: 'STAGE_SPRITE'
inputOp: 'videoSensing.menu.SUBJECT',
inputName: 'SUBJECT'
}
]
},
Expand Down
16 changes: 8 additions & 8 deletions test/unit/extension_video_sensing.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,35 +337,35 @@ test('videoOn returns value dependent on arguments', t => {
sensing.detect.addFrame(frames.left);

const motionAmount = sensing.videoOn({
MOTION_DIRECTION: VideoSensing.MOTION,
STAGE_SPRITE: VideoSensing.STAGE
ATTRIBUTE: VideoSensing.SensingAttribute.MOTION,
SUBJECT: VideoSensing.SensingSubject.STAGE
}, fakeBlockUtility);
t.ok(
motionAmount > 10,
`stage motionAmount ${motionAmount} is over the threshold (10)`
);

const localMotionAmount = sensing.videoOn({
MOTION_DIRECTION: VideoSensing.MOTION,
STAGE_SPRITE: VideoSensing.SPRITE
ATTRIBUTE: VideoSensing.SensingAttribute.MOTION,
SUBJECT: VideoSensing.SensingSubject.SPRITE
}, fakeBlockUtility);
t.ok(
localMotionAmount > 10,
`sprite motionAmount ${localMotionAmount} is over the threshold (10)`
);

const motionDirection = sensing.videoOn({
MOTION_DIRECTION: VideoSensing.DIRECTION,
STAGE_SPRITE: VideoSensing.STAGE
ATTRIBUTE: VideoSensing.SensingAttribute.DIRECTION,
SUBJECT: VideoSensing.SensingSubject.STAGE
}, fakeBlockUtility);
t.ok(
isNearAngle(motionDirection, -90),
`stage motionDirection ${motionDirection.toFixed(0)} degrees is close to ${90} degrees`
);

const localMotionDirection = sensing.videoOn({
MOTION_DIRECTION: VideoSensing.DIRECTION,
STAGE_SPRITE: VideoSensing.SPRITE
ATTRIBUTE: VideoSensing.SensingAttribute.DIRECTION,
SUBJECT: VideoSensing.SensingSubject.SPRITE
}, fakeBlockUtility);
t.ok(
isNearAngle(localMotionDirection, -90),
Expand Down

0 comments on commit 3ac2922

Please sign in to comment.