@scratch/scratch-vm 11.0.0-UEPR-176
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +12 -0
- package/README.md +120 -0
- package/dist/node/extension-worker.js +2 -0
- package/dist/node/extension-worker.js.map +1 -0
- package/dist/node/scratch-vm.js +3 -0
- package/dist/node/scratch-vm.js.LICENSE.txt +205 -0
- package/dist/node/scratch-vm.js.map +1 -0
- package/dist/web/extension-worker.js +2 -0
- package/dist/web/extension-worker.js.map +1 -0
- package/dist/web/scratch-vm.js +3 -0
- package/dist/web/scratch-vm.js.LICENSE.txt +42 -0
- package/dist/web/scratch-vm.js.map +1 -0
- package/package.json +108 -0
- package/src/.eslintrc.js +7 -0
- package/src/blocks/scratch3_control.js +206 -0
- package/src/blocks/scratch3_core_example.js +69 -0
- package/src/blocks/scratch3_data.js +257 -0
- package/src/blocks/scratch3_event.js +137 -0
- package/src/blocks/scratch3_looks.js +612 -0
- package/src/blocks/scratch3_motion.js +288 -0
- package/src/blocks/scratch3_operators.js +154 -0
- package/src/blocks/scratch3_procedures.js +79 -0
- package/src/blocks/scratch3_sensing.js +336 -0
- package/src/blocks/scratch3_sound.js +350 -0
- package/src/dispatch/central-dispatch.js +143 -0
- package/src/dispatch/shared-dispatch.js +235 -0
- package/src/dispatch/worker-dispatch.js +110 -0
- package/src/engine/adapter.js +176 -0
- package/src/engine/block-utility.js +242 -0
- package/src/engine/blocks-execute-cache.js +19 -0
- package/src/engine/blocks-runtime-cache.js +78 -0
- package/src/engine/blocks.js +1299 -0
- package/src/engine/comment.js +56 -0
- package/src/engine/execute.js +580 -0
- package/src/engine/monitor-record.js +23 -0
- package/src/engine/mutation-adapter.js +48 -0
- package/src/engine/profiler.js +390 -0
- package/src/engine/runtime.js +2686 -0
- package/src/engine/scratch-blocks-constants.js +27 -0
- package/src/engine/sequencer.js +361 -0
- package/src/engine/stage-layering.js +29 -0
- package/src/engine/target.js +799 -0
- package/src/engine/thread.js +404 -0
- package/src/engine/variable.js +70 -0
- package/src/extension-support/argument-type.js +47 -0
- package/src/extension-support/block-type.js +50 -0
- package/src/extension-support/define-messages.js +18 -0
- package/src/extension-support/extension-manager.js +440 -0
- package/src/extension-support/extension-metadata.js +64 -0
- package/src/extension-support/extension-worker.js +59 -0
- package/src/extension-support/reporter-scope.js +18 -0
- package/src/extension-support/target-type.js +17 -0
- package/src/extensions/scratch3_boost/index.js +2113 -0
- package/src/extensions/scratch3_ev3/index.js +1355 -0
- package/src/extensions/scratch3_gdx_for/index.js +981 -0
- package/src/extensions/scratch3_gdx_for/scratch-link-device-adapter.js +44 -0
- package/src/extensions/scratch3_makeymakey/index.js +396 -0
- package/src/extensions/scratch3_microbit/index.js +984 -0
- package/src/extensions/scratch3_music/assets/drums/1-snare.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/10-wood-block.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/11-cowbell.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/12-triangle.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/13-bongo.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/14-conga.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/15-cabasa.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/16-guiro.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/17-vibraslap.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/18-cuica.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/2-bass-drum.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/3-side-stick.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/4-crash-cymbal.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/5-open-hi-hat.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/6-closed-hi-hat.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/7-tambourine.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/8-hand-clap.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/drums/9-claves.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/1-piano/108.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/1-piano/24.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/1-piano/36.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/1-piano/48.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/1-piano/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/1-piano/72.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/1-piano/84.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/1-piano/96.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/10-clarinet/48.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/10-clarinet/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/11-saxophone/36.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/11-saxophone/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/11-saxophone/84.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/12-flute/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/12-flute/72.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/13-wooden-flute/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/13-wooden-flute/72.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/14-bassoon/36.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/14-bassoon/48.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/14-bassoon/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/15-choir/48.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/15-choir/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/15-choir/72.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/16-vibraphone/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/16-vibraphone/72.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/17-music-box/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/18-steel-drum/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/19-marimba/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/2-electric-piano/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/20-synth-lead/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/21-synth-pad/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/3-organ/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/4-guitar/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/5-electric-guitar/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/6-bass/36.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/6-bass/48.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/7-pizzicato/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/8-cello/36.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/8-cello/48.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/8-cello/60.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/9-trombone/36.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/9-trombone/48.mp3 +0 -0
- package/src/extensions/scratch3_music/assets/instruments/9-trombone/60.mp3 +0 -0
- package/src/extensions/scratch3_music/index.js +1333 -0
- package/src/extensions/scratch3_music/manifest.js +63 -0
- package/src/extensions/scratch3_pen/index.js +770 -0
- package/src/extensions/scratch3_speech2text/index.js +700 -0
- package/src/extensions/scratch3_text2speech/index.js +766 -0
- package/src/extensions/scratch3_translate/index.js +286 -0
- package/src/extensions/scratch3_video_sensing/debug.js +13 -0
- package/src/extensions/scratch3_video_sensing/index.js +594 -0
- package/src/extensions/scratch3_video_sensing/library.js +384 -0
- package/src/extensions/scratch3_video_sensing/math.js +76 -0
- package/src/extensions/scratch3_video_sensing/view.js +509 -0
- package/src/extensions/scratch3_wedo2/index.js +1616 -0
- package/src/import/load-costume.js +416 -0
- package/src/import/load-sound.js +116 -0
- package/src/index.js +10 -0
- package/src/io/ble.js +256 -0
- package/src/io/bt.js +202 -0
- package/src/io/clock.js +39 -0
- package/src/io/cloud.js +169 -0
- package/src/io/keyboard.js +146 -0
- package/src/io/mouse.js +145 -0
- package/src/io/mouseWheel.js +28 -0
- package/src/io/userData.js +24 -0
- package/src/io/video.js +210 -0
- package/src/playground/benchmark.css +83 -0
- package/src/playground/benchmark.js +753 -0
- package/src/playground/index.html +111 -0
- package/src/playground/suite.css +78 -0
- package/src/playground/suite.html +25 -0
- package/src/playground/suite.js +544 -0
- package/src/playground/video-sensing.html +18 -0
- package/src/playground/video-sensing.js +133 -0
- package/src/serialization/deserialize-assets.js +178 -0
- package/src/serialization/sb2.js +1295 -0
- package/src/serialization/sb2_specmap.js +1818 -0
- package/src/serialization/sb3.js +1320 -0
- package/src/serialization/serialize-assets.js +60 -0
- package/src/sprites/rendered-target.js +1115 -0
- package/src/sprites/sprite.js +177 -0
- package/src/util/base64-util.js +48 -0
- package/src/util/cast.js +218 -0
- package/src/util/clone.js +17 -0
- package/src/util/color.js +204 -0
- package/src/util/fetch-with-timeout.js +53 -0
- package/src/util/get-monitor-id.js +33 -0
- package/src/util/jsonrpc.js +114 -0
- package/src/util/log.js +4 -0
- package/src/util/math-util.js +122 -0
- package/src/util/maybe-format-message.js +18 -0
- package/src/util/new-block-ids.js +33 -0
- package/src/util/rateLimiter.js +73 -0
- package/src/util/scratch-link-websocket.js +133 -0
- package/src/util/string-util.js +94 -0
- package/src/util/task-queue.js +203 -0
- package/src/util/timer.js +103 -0
- package/src/util/uid.js +29 -0
- package/src/util/variable-util.js +48 -0
- package/src/util/xml-escape.js +33 -0
- package/src/virtual-machine.js +1586 -0
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
const {motionVector} = require('./math');
|
|
2
|
+
|
|
3
|
+
const WIDTH = 480;
|
|
4
|
+
const HEIGHT = 360;
|
|
5
|
+
const WINSIZE = 8;
|
|
6
|
+
const AMOUNT_SCALE = 100;
|
|
7
|
+
const THRESHOLD = 10;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Modes of debug output that can be rendered.
|
|
11
|
+
* @type {object}
|
|
12
|
+
*/
|
|
13
|
+
const OUTPUT = {
|
|
14
|
+
/**
|
|
15
|
+
* Render the original input.
|
|
16
|
+
* @type {number}
|
|
17
|
+
*/
|
|
18
|
+
INPUT: -1,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Render the difference of neighboring pixels for each pixel. The
|
|
22
|
+
* horizontal difference, or x value, renders in the red output component.
|
|
23
|
+
* The vertical difference, or y value, renders in the green output
|
|
24
|
+
* component. Pixels with equal neighbors with a kind of lime green or
|
|
25
|
+
* #008080 in a RGB hex value. Colors with more red have a lower value to
|
|
26
|
+
* the right than the value to the left. Colors with less red have a higher
|
|
27
|
+
* value to the right than the value to the left. Similarly colors with
|
|
28
|
+
* more green have lower values below than above and colors with less green
|
|
29
|
+
* have higher values below than above.
|
|
30
|
+
* @type {number}
|
|
31
|
+
*/
|
|
32
|
+
XY: 0,
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Render the XY output with groups of pixels averaged together. The group
|
|
36
|
+
* shape and size matches the full frame's analysis window size.
|
|
37
|
+
* @type {number}
|
|
38
|
+
*/
|
|
39
|
+
XY_CELL: 1,
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Render three color components matching the detection algorith's values
|
|
43
|
+
* that multiple the horizontal difference, or x value, and the vertical
|
|
44
|
+
* difference, or y value together. The red component is the x value
|
|
45
|
+
* squared. The green component is the y value squared. The blue component
|
|
46
|
+
* is the x value times the y value. The detection code refers to these
|
|
47
|
+
* values as A2, B1, and A1B2.
|
|
48
|
+
* @type {number}
|
|
49
|
+
*/
|
|
50
|
+
AB: 2,
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Render the AB output of groups of pixels summarized by their combined
|
|
54
|
+
* square root. The group shape and size matches the full frame's analysis
|
|
55
|
+
* window size.
|
|
56
|
+
* @type {number}
|
|
57
|
+
*/
|
|
58
|
+
AB_CELL: 3,
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Render a single color component matching the temporal difference or the
|
|
62
|
+
* difference in color for the same pixel coordinate in the current frame
|
|
63
|
+
* and the last frame. The difference is rendered in the blue color
|
|
64
|
+
* component since x and y axis differences tend to use red and green.
|
|
65
|
+
* @type {number}
|
|
66
|
+
*/
|
|
67
|
+
T: 4,
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Render the T output of groups of pixels averaged. The group shape and
|
|
71
|
+
* size matches the full frame's analysis window.
|
|
72
|
+
* @type {number}
|
|
73
|
+
*/
|
|
74
|
+
T_CELL: 5,
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Render the XY and T outputs together. The x and y axis values use the
|
|
78
|
+
* red and green color components as they do in the XY output. The t values
|
|
79
|
+
* use the blue color component as the T output does.
|
|
80
|
+
* @type {number}
|
|
81
|
+
*/
|
|
82
|
+
XYT: 6,
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Render the XYT output of groups of pixels averaged. The group shape and
|
|
86
|
+
* size matches the full frame's analysis window.
|
|
87
|
+
* @type {number}
|
|
88
|
+
*/
|
|
89
|
+
XYT_CELL: 7,
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Render the horizontal pixel difference times the temporal difference as
|
|
93
|
+
* red and the vertical and temporal difference as green. Multiplcation of
|
|
94
|
+
* these values ends up with sharp differences in the output showing edge
|
|
95
|
+
* details where motion is happening.
|
|
96
|
+
* @type {number}
|
|
97
|
+
*/
|
|
98
|
+
C: 8,
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Render the C output of groups of pixels averaged. The group shape and
|
|
102
|
+
* size matches the full frame's analysis window.
|
|
103
|
+
* @type {number}
|
|
104
|
+
*/
|
|
105
|
+
C_CELL: 9,
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Render a per pixel version of UV_CELL. UV_CELL is a close to final step
|
|
109
|
+
* of the motion code that builds a motion amount and direction from those
|
|
110
|
+
* values. UV_CELL renders grouped summarized values, UV does the per pixel
|
|
111
|
+
* version but its can only represent one motion vector code path out of
|
|
112
|
+
* two choices. Determining the motion vector compares some of the built
|
|
113
|
+
* values but building the values with one pixel ensures this first
|
|
114
|
+
* comparison says the values are equal. Even though only one code path is
|
|
115
|
+
* used to build the values, its output is close to approximating the
|
|
116
|
+
* better solution building vectors from groups of pixels to help
|
|
117
|
+
* illustrate when the code determines the motion amount and direction to
|
|
118
|
+
* be.
|
|
119
|
+
* @type {number}
|
|
120
|
+
*/
|
|
121
|
+
UV: 10,
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Render cells of mulitple pixels at a step in the motion code that has
|
|
125
|
+
* the same cell values and turns them into motion vectors showing the
|
|
126
|
+
* amount of motion in the x axis and y axis separately. Those values are a
|
|
127
|
+
* step away from becoming a motion amount and direction through standard
|
|
128
|
+
* vector to magnitude and angle values.
|
|
129
|
+
* @type {number}
|
|
130
|
+
*/
|
|
131
|
+
UV_CELL: 11
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Temporary storage structure for returning values in
|
|
136
|
+
* VideoMotionView._components.
|
|
137
|
+
* @type {object}
|
|
138
|
+
*/
|
|
139
|
+
const _videoMotionViewComponentsTmp = {
|
|
140
|
+
A2: 0,
|
|
141
|
+
A1B2: 0,
|
|
142
|
+
B1: 0,
|
|
143
|
+
C2: 0,
|
|
144
|
+
C1: 0
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Manage a debug canvas with VideoMotion input frames running parts of what
|
|
149
|
+
* VideoMotion does to visualize what it does.
|
|
150
|
+
* @param {VideoMotion} motion - VideoMotion with inputs to visualize
|
|
151
|
+
* @param {OUTPUT} output - visualization output mode
|
|
152
|
+
* @constructor
|
|
153
|
+
*/
|
|
154
|
+
class VideoMotionView {
|
|
155
|
+
constructor (motion, output = OUTPUT.XYT) {
|
|
156
|
+
/**
|
|
157
|
+
* VideoMotion instance to visualize.
|
|
158
|
+
* @type {VideoMotion}
|
|
159
|
+
*/
|
|
160
|
+
this.motion = motion;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Debug canvas to render to.
|
|
164
|
+
* @type {HTMLCanvasElement}
|
|
165
|
+
*/
|
|
166
|
+
const canvas = this.canvas = document.createElement('canvas');
|
|
167
|
+
canvas.width = WIDTH;
|
|
168
|
+
canvas.height = HEIGHT;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* 2D context to draw to debug canvas.
|
|
172
|
+
* @type {CanvasRendering2DContext}
|
|
173
|
+
*/
|
|
174
|
+
this.context = canvas.getContext('2d');
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Visualization output mode.
|
|
178
|
+
* @type {OUTPUT}
|
|
179
|
+
*/
|
|
180
|
+
this.output = output;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Pixel buffer to store output values into before they replace the last frames info in the debug canvas.
|
|
184
|
+
* @type {Uint32Array}
|
|
185
|
+
*/
|
|
186
|
+
this.buffer = new Uint32Array(WIDTH * HEIGHT);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Modes of debug output that can be rendered.
|
|
191
|
+
* @type {object}
|
|
192
|
+
*/
|
|
193
|
+
static get OUTPUT () {
|
|
194
|
+
return OUTPUT;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Iterate each pixel address location and call a function with that address.
|
|
199
|
+
* @param {number} xStart - start location on the x axis of the output pixel buffer
|
|
200
|
+
* @param {number} yStart - start location on the y axis of the output pixel buffer
|
|
201
|
+
* @param {nubmer} xStop - location to stop at on the x axis
|
|
202
|
+
* @param {number} yStop - location to stop at on the y axis
|
|
203
|
+
* @param {function} fn - handle to call with each iterated address
|
|
204
|
+
*/
|
|
205
|
+
_eachAddress (xStart, yStart, xStop, yStop, fn) {
|
|
206
|
+
for (let i = yStart; i < yStop; i++) {
|
|
207
|
+
for (let j = xStart; j < xStop; j++) {
|
|
208
|
+
const address = (i * WIDTH) + j;
|
|
209
|
+
fn(address, j, i);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Iterate over cells of pixels and call a function with a function to
|
|
216
|
+
* iterate over pixel addresses.
|
|
217
|
+
* @param {number} xStart - start location on the x axis
|
|
218
|
+
* @param {number} yStart - start lcoation on the y axis
|
|
219
|
+
* @param {number} xStop - location to stop at on the x axis
|
|
220
|
+
* @param {number} yStop - location to stop at on the y axis
|
|
221
|
+
* @param {number} xStep - width of the cells
|
|
222
|
+
* @param {number} yStep - height of the cells
|
|
223
|
+
* @param {function} fn - function to call with a bound handle to _eachAddress
|
|
224
|
+
*/
|
|
225
|
+
_eachCell (xStart, yStart, xStop, yStop, xStep, yStep, fn) {
|
|
226
|
+
const xStep2 = (xStep / 2) | 0;
|
|
227
|
+
const yStep2 = (yStep / 2) | 0;
|
|
228
|
+
for (let i = yStart; i < yStop; i += yStep) {
|
|
229
|
+
for (let j = xStart; j < xStop; j += xStep) {
|
|
230
|
+
fn(
|
|
231
|
+
_fn => this._eachAddress(j - xStep2 - 1, i - yStep2 - 1, j + xStep2, i + yStep2, _fn),
|
|
232
|
+
j - xStep2 - 1,
|
|
233
|
+
i - yStep2 - 1,
|
|
234
|
+
j + xStep2,
|
|
235
|
+
i + yStep2
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Build horizontal, vertical, and temporal difference of a pixel address.
|
|
243
|
+
* @param {number} address - address to build values for
|
|
244
|
+
* @returns {object} a object with a gradX, grady, and gradT value
|
|
245
|
+
*/
|
|
246
|
+
_grads (address) {
|
|
247
|
+
const {curr, prev} = this.motion;
|
|
248
|
+
const gradX = (curr[address - 1] & 0xff) - (curr[address + 1] & 0xff);
|
|
249
|
+
const gradY = (curr[address - WIDTH] & 0xff) - (curr[address + WIDTH] & 0xff);
|
|
250
|
+
const gradT = (prev[address] & 0xff) - (curr[address] & 0xff);
|
|
251
|
+
return {gradX, gradY, gradT};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Build component values used in determining a motion vector for a pixel
|
|
256
|
+
* address.
|
|
257
|
+
* @param {function} eachAddress - a bound handle to _eachAddress to build
|
|
258
|
+
* component values for
|
|
259
|
+
* @returns {object} a object with a A2, A1B2, B1, C2, C1 value
|
|
260
|
+
*/
|
|
261
|
+
_components (eachAddress) {
|
|
262
|
+
let A2 = 0;
|
|
263
|
+
let A1B2 = 0;
|
|
264
|
+
let B1 = 0;
|
|
265
|
+
let C2 = 0;
|
|
266
|
+
let C1 = 0;
|
|
267
|
+
|
|
268
|
+
eachAddress(address => {
|
|
269
|
+
const {gradX, gradY, gradT} = this._grads(address);
|
|
270
|
+
A2 += gradX * gradX;
|
|
271
|
+
A1B2 += gradX * gradY;
|
|
272
|
+
B1 += gradY * gradY;
|
|
273
|
+
C2 += gradX * gradT;
|
|
274
|
+
C1 += gradY * gradT;
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
_videoMotionViewComponentsTmp.A2 = A2;
|
|
278
|
+
_videoMotionViewComponentsTmp.A1B2 = A1B2;
|
|
279
|
+
_videoMotionViewComponentsTmp.B1 = B1;
|
|
280
|
+
_videoMotionViewComponentsTmp.C2 = C2;
|
|
281
|
+
_videoMotionViewComponentsTmp.C1 = C1;
|
|
282
|
+
return _videoMotionViewComponentsTmp;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Visualize the motion code output mode selected for this view to the
|
|
287
|
+
* debug canvas.
|
|
288
|
+
*/
|
|
289
|
+
draw () {
|
|
290
|
+
if (!(this.motion.prev && this.motion.curr)) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const {buffer} = this;
|
|
295
|
+
|
|
296
|
+
if (this.output === OUTPUT.INPUT) {
|
|
297
|
+
const {curr} = this.motion;
|
|
298
|
+
this._eachAddress(1, 1, WIDTH - 1, HEIGHT - 1, address => {
|
|
299
|
+
buffer[address] = curr[address];
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
if (this.output === OUTPUT.XYT) {
|
|
303
|
+
this._eachAddress(1, 1, WIDTH - 1, HEIGHT - 1, address => {
|
|
304
|
+
const {gradX, gradY, gradT} = this._grads(address);
|
|
305
|
+
const over1 = gradT / 0xcf;
|
|
306
|
+
buffer[address] =
|
|
307
|
+
(0xff << 24) +
|
|
308
|
+
(Math.floor((((gradY * over1) & 0xff) + 0xff) / 2) << 8) +
|
|
309
|
+
Math.floor((((gradX * over1) & 0xff) + 0xff) / 2);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
if (this.output === OUTPUT.XYT_CELL) {
|
|
313
|
+
const winStep = (WINSIZE * 2) + 1;
|
|
314
|
+
const wmax = WIDTH - WINSIZE - 1;
|
|
315
|
+
const hmax = HEIGHT - WINSIZE - 1;
|
|
316
|
+
|
|
317
|
+
this._eachCell(WINSIZE + 1, WINSIZE + 1, wmax, hmax, winStep, winStep, eachAddress => {
|
|
318
|
+
let C1 = 0;
|
|
319
|
+
let C2 = 0;
|
|
320
|
+
let n = 0;
|
|
321
|
+
|
|
322
|
+
eachAddress(address => {
|
|
323
|
+
const {gradX, gradY, gradT} = this._grads(address);
|
|
324
|
+
C2 += (Math.max(Math.min(gradX / 0x0f, 1), -1)) * (gradT / 0xff);
|
|
325
|
+
C1 += (Math.max(Math.min(gradY / 0x0f, 1), -1)) * (gradT / 0xff);
|
|
326
|
+
n += 1;
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
C1 /= n;
|
|
330
|
+
C2 /= n;
|
|
331
|
+
C1 = Math.log(C1 + (1 * Math.sign(C1))) / Math.log(2);
|
|
332
|
+
C2 = Math.log(C2 + (1 * Math.sign(C2))) / Math.log(2);
|
|
333
|
+
|
|
334
|
+
eachAddress(address => {
|
|
335
|
+
buffer[address] = (0xff << 24) +
|
|
336
|
+
(((((C1 * 0x7f) | 0) + 0x80) << 8) & 0xff00) +
|
|
337
|
+
(((((C2 * 0x7f) | 0) + 0x80) << 0) & 0xff);
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
if (this.output === OUTPUT.XY) {
|
|
342
|
+
this._eachAddress(1, 1, WIDTH - 1, HEIGHT - 1, address => {
|
|
343
|
+
const {gradX, gradY} = this._grads(address);
|
|
344
|
+
buffer[address] = (0xff << 24) + (((gradY + 0xff) / 2) << 8) + ((gradX + 0xff) / 2);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
if (this.output === OUTPUT.XY_CELL) {
|
|
348
|
+
const winStep = (WINSIZE * 2) + 1;
|
|
349
|
+
const wmax = WIDTH - WINSIZE - 1;
|
|
350
|
+
const hmax = HEIGHT - WINSIZE - 1;
|
|
351
|
+
|
|
352
|
+
this._eachCell(WINSIZE + 1, WINSIZE + 1, wmax, hmax, winStep, winStep, eachAddress => {
|
|
353
|
+
let C1 = 0;
|
|
354
|
+
let C2 = 0;
|
|
355
|
+
let n = 0;
|
|
356
|
+
|
|
357
|
+
eachAddress(address => {
|
|
358
|
+
const {gradX, gradY} = this._grads(address);
|
|
359
|
+
C2 += Math.max(Math.min(gradX / 0x1f, 1), -1);
|
|
360
|
+
C1 += Math.max(Math.min(gradY / 0x1f, 1), -1);
|
|
361
|
+
n += 1;
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
C1 /= n;
|
|
365
|
+
C2 /= n;
|
|
366
|
+
C1 = Math.log(C1 + (1 * Math.sign(C1))) / Math.log(2);
|
|
367
|
+
C2 = Math.log(C2 + (1 * Math.sign(C2))) / Math.log(2);
|
|
368
|
+
|
|
369
|
+
eachAddress(address => {
|
|
370
|
+
buffer[address] = (0xff << 24) +
|
|
371
|
+
(((((C1 * 0x7f) | 0) + 0x80) << 8) & 0xff00) +
|
|
372
|
+
(((((C2 * 0x7f) | 0) + 0x80) << 0) & 0xff);
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
} else if (this.output === OUTPUT.T) {
|
|
376
|
+
this._eachAddress(1, 1, WIDTH - 1, HEIGHT - 1, address => {
|
|
377
|
+
const {gradT} = this._grads(address);
|
|
378
|
+
buffer[address] = (0xff << 24) + ((gradT + 0xff) / 2 << 16);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
if (this.output === OUTPUT.T_CELL) {
|
|
382
|
+
const winStep = (WINSIZE * 2) + 1;
|
|
383
|
+
const wmax = WIDTH - WINSIZE - 1;
|
|
384
|
+
const hmax = HEIGHT - WINSIZE - 1;
|
|
385
|
+
|
|
386
|
+
this._eachCell(WINSIZE + 1, WINSIZE + 1, wmax, hmax, winStep, winStep, eachAddress => {
|
|
387
|
+
let T = 0;
|
|
388
|
+
let n = 0;
|
|
389
|
+
|
|
390
|
+
eachAddress(address => {
|
|
391
|
+
const {gradT} = this._grads(address);
|
|
392
|
+
T += gradT / 0xff;
|
|
393
|
+
n += 1;
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
T /= n;
|
|
397
|
+
|
|
398
|
+
eachAddress(address => {
|
|
399
|
+
buffer[address] = (0xff << 24) +
|
|
400
|
+
(((((T * 0x7f) | 0) + 0x80) << 16) & 0xff0000);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
} else if (this.output === OUTPUT.C) {
|
|
404
|
+
this._eachAddress(1, 1, WIDTH - 1, HEIGHT - 1, address => {
|
|
405
|
+
const {gradX, gradY, gradT} = this._grads(address);
|
|
406
|
+
buffer[address] =
|
|
407
|
+
(0xff << 24) +
|
|
408
|
+
(((Math.sqrt(gradY * gradT) * 0x0f) & 0xff) << 8) +
|
|
409
|
+
((Math.sqrt(gradX * gradT) * 0x0f) & 0xff);
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
if (this.output === OUTPUT.C_CELL) {
|
|
413
|
+
const winStep = (WINSIZE * 2) + 1;
|
|
414
|
+
const wmax = WIDTH - WINSIZE - 1;
|
|
415
|
+
const hmax = HEIGHT - WINSIZE - 1;
|
|
416
|
+
|
|
417
|
+
this._eachCell(WINSIZE + 1, WINSIZE + 1, wmax, hmax, winStep, winStep, eachAddress => {
|
|
418
|
+
let {C2, C1} = this._components(eachAddress);
|
|
419
|
+
|
|
420
|
+
C2 = Math.sqrt(C2);
|
|
421
|
+
C1 = Math.sqrt(C1);
|
|
422
|
+
|
|
423
|
+
eachAddress(address => {
|
|
424
|
+
buffer[address] =
|
|
425
|
+
(0xff << 24) +
|
|
426
|
+
((C1 & 0xff) << 8) +
|
|
427
|
+
((C2 & 0xff) << 0);
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
} else if (this.output === OUTPUT.AB) {
|
|
431
|
+
this._eachAddress(1, 1, WIDTH - 1, HEIGHT - 1, address => {
|
|
432
|
+
const {gradX, gradY} = this._grads(address);
|
|
433
|
+
buffer[address] =
|
|
434
|
+
(0xff << 24) +
|
|
435
|
+
(((gradX * gradY) & 0xff) << 16) +
|
|
436
|
+
(((gradY * gradY) & 0xff) << 8) +
|
|
437
|
+
((gradX * gradX) & 0xff);
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
if (this.output === OUTPUT.AB_CELL) {
|
|
441
|
+
const winStep = (WINSIZE * 2) + 1;
|
|
442
|
+
const wmax = WIDTH - WINSIZE - 1;
|
|
443
|
+
const hmax = HEIGHT - WINSIZE - 1;
|
|
444
|
+
|
|
445
|
+
this._eachCell(WINSIZE + 1, WINSIZE + 1, wmax, hmax, winStep, winStep, eachAddress => {
|
|
446
|
+
let {A2, A1B2, B1} = this._components(eachAddress);
|
|
447
|
+
|
|
448
|
+
A2 = Math.sqrt(A2);
|
|
449
|
+
A1B2 = Math.sqrt(A1B2);
|
|
450
|
+
B1 = Math.sqrt(B1);
|
|
451
|
+
|
|
452
|
+
eachAddress(address => {
|
|
453
|
+
buffer[address] =
|
|
454
|
+
(0xff << 24) +
|
|
455
|
+
((A1B2 & 0xff) << 16) +
|
|
456
|
+
((B1 & 0xff) << 8) +
|
|
457
|
+
(A2 & 0xff);
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
} else if (this.output === OUTPUT.UV) {
|
|
461
|
+
const winStep = (WINSIZE * 2) + 1;
|
|
462
|
+
|
|
463
|
+
this._eachAddress(1, 1, WIDTH - 1, HEIGHT - 1, address => {
|
|
464
|
+
const {A2, A1B2, B1, C2, C1} = this._components(fn => fn(address));
|
|
465
|
+
const {u, v} = motionVector(A2, A1B2, B1, C2, C1);
|
|
466
|
+
|
|
467
|
+
const inRange = (-winStep < u && u < winStep && -winStep < v && v < winStep);
|
|
468
|
+
const hypot = Math.hypot(u, v);
|
|
469
|
+
const amount = AMOUNT_SCALE * hypot;
|
|
470
|
+
|
|
471
|
+
buffer[address] =
|
|
472
|
+
(0xff << 24) +
|
|
473
|
+
(inRange && amount > THRESHOLD ?
|
|
474
|
+
(((((v / winStep) + 1) / 2 * 0xff) << 8) & 0xff00) +
|
|
475
|
+
(((((u / winStep) + 1) / 2 * 0xff) << 0) & 0xff) :
|
|
476
|
+
0x8080
|
|
477
|
+
);
|
|
478
|
+
});
|
|
479
|
+
} else if (this.output === OUTPUT.UV_CELL) {
|
|
480
|
+
const winStep = (WINSIZE * 2) + 1;
|
|
481
|
+
const wmax = WIDTH - WINSIZE - 1;
|
|
482
|
+
const hmax = HEIGHT - WINSIZE - 1;
|
|
483
|
+
|
|
484
|
+
this._eachCell(WINSIZE + 1, WINSIZE + 1, wmax, hmax, winStep, winStep, eachAddress => {
|
|
485
|
+
const {A2, A1B2, B1, C2, C1} = this._components(eachAddress);
|
|
486
|
+
const {u, v} = motionVector(A2, A1B2, B1, C2, C1);
|
|
487
|
+
|
|
488
|
+
const inRange = (-winStep < u && u < winStep && -winStep < v && v < winStep);
|
|
489
|
+
const hypot = Math.hypot(u, v);
|
|
490
|
+
const amount = AMOUNT_SCALE * hypot;
|
|
491
|
+
|
|
492
|
+
eachAddress(address => {
|
|
493
|
+
buffer[address] =
|
|
494
|
+
(0xff << 24) +
|
|
495
|
+
(inRange && amount > THRESHOLD ?
|
|
496
|
+
(((((v / winStep) + 1) / 2 * 0xff) << 8) & 0xff00) +
|
|
497
|
+
(((((u / winStep) + 1) / 2 * 0xff) << 0) & 0xff) :
|
|
498
|
+
0x8080
|
|
499
|
+
);
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const data = new ImageData(new Uint8ClampedArray(this.buffer.buffer), WIDTH, HEIGHT);
|
|
505
|
+
this.context.putImageData(data, 0, 0);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
module.exports = VideoMotionView;
|