UNPKG

aframe-motion-capture-components

Version:
412 lines (361 loc) 14.6 kB
/* global assert, setup, suite, test */ require('aframe'); require('../src/index.js'); const helpers = require('./helpers'); suite('avatar-recorder', function () { var component; var sceneEl; setup(function (done) { sceneEl = document.createElement('a-scene'); sceneEl.addEventListener('componentinitialized', evt => { if (evt.detail.name !== 'avatar-recorder') { return; } if (sceneEl.systems.recordingdb.hasLoaded) { component = sceneEl.components['avatar-recorder']; waitForCamera(); } else { sceneEl.addEventListener('recordingdbinitialized', function () { component = sceneEl.components['avatar-recorder']; waitForCamera(); }); } }); function waitForCamera () { if (sceneEl.camera) { done(); return; } sceneEl.addEventListener('camera-set-active', function () { done(); }); } sceneEl.setAttribute('avatar-recorder', ''); document.body.appendChild(sceneEl); }); teardown(function () { // https://github.com/aframevr/aframe/pull/2302 window.removeEventListener('keydown', component.onKeyDown); }); test('gets the camera element', function () { component.startRecording(); assert.equal(component.cameraEl, sceneEl.camera.el); }); test('sets motion-capture-recorder on camera', function () { sceneEl.addEventListener('camera-set-active', () => { component.startRecording(); assert.ok(sceneEl.camera.el.getAttribute('motion-capture-recorder')); done(); }); }); test('sets motion-capture-recorder on tracked controllers', function (done) { var controllers; // Create controllers. const c1 = document.createElement('a-entity'); c1.setAttribute('id', 'c1'); c1.setAttribute('tracked-controls', ''); const c2 = document.createElement('a-entity'); c2.setAttribute('id', 'c2'); c2.setAttribute('tracked-controls', ''); component.throttledTick(); controllers = component.trackedControllerEls; assert.notOk('c1' in controllers, 'Controller 1 not appended yet'); assert.notOk('c2' in controllers, 'Controller 2 not appended yet'); sceneEl.appendChild(c1); sceneEl.appendChild(c2); setTimeout(() => { component.throttledTick(); controllers = component.trackedControllerEls; assert.ok('c1' in controllers, 'Controller 1 detected'); assert.ok('c2' in controllers, 'Controller 2 detected'); done(); }); }); test('adds recording to IndexedDB', function (done) { sceneEl.setAttribute('avatar-recorder', 'recordingName', 'foo'); component.startRecording(); component.recordingData = {camera: {poses: [{timestamp: 0}], events: []}}; component.isRecording = true; component.stopRecording(); sceneEl.systems.recordingdb.getRecording('foo').then(data => { assert.shallowDeepEqual(data, component.recordingData); done(); }); }); }); suite('avatar-replayer', function () { var component; var sceneEl; setup(function (done) { sceneEl = document.createElement('a-scene'); sceneEl.addEventListener('componentinitialized', evt => { if (evt.detail.name !== 'avatar-replayer') { return; } component = sceneEl.components['avatar-replayer']; done(); }); sceneEl.setAttribute('avatar-replayer', ''); document.body.appendChild(sceneEl); }); test('sets motion-capture-replayer on camera and controllers', (done) => { const c1 = document.createElement('a-entity'); c1.setAttribute('id', 'c1'); c1.setAttribute('tracked-controls', ''); sceneEl.appendChild(c1); const c2 = document.createElement('a-entity'); c2.setAttribute('id', 'c2'); c2.setAttribute('tracked-controls', ''); sceneEl.appendChild(c2); sceneEl.addEventListener('camera-set-active', () => { sceneEl.components['avatar-replayer'].startReplaying({ camera: {poses: [{timestamp: 0}], events: []}, c1: {poses: [{timestamp: 0}], events: []}, c2: {poses: [{timestamp: 0}], events: []} }); assert.ok(sceneEl.camera.el.getAttribute('motion-capture-replayer')); assert.ok(c1.getAttribute('motion-capture-replayer')); assert.ok(c2.getAttribute('motion-capture-replayer')); done(); }); }); test('calls startReplaying on motion-capture-replayer', function (done) { const c1 = document.createElement('a-entity'); c1.setAttribute('id', 'c1'); c1.setAttribute('tracked-controls', ''); c1.setAttribute('motion-capture-replayer', ''); const c1StartPlayingSpy = this.sinon.spy(c1.components['motion-capture-replayer'], 'startReplaying'); sceneEl.appendChild(c1); sceneEl.addEventListener('camera-set-active', () => { component.startReplaying({ camera: {poses: [{timestamp: 0}], events: []}, c1: {poses: [{timestamp: 0}], events: []}, }); assert.ok(c1StartPlayingSpy.called); done(); }); }); }); suite('motion-capture-recorder', function () { var component; var el; setup(function (done) { el = helpers.entityFactory(); el.addEventListener('componentinitialized', evt => { if (evt.detail.name !== 'motion-capture-recorder') { return; } component = el.components['motion-capture-recorder']; done(); }); el.setAttribute('motion-capture-recorder', ''); }); suite('tick', function () { test('records poses', function () { assert.equal(component.recordedPoses.length, 0); el.setAttribute('position', '1 1 1'); el.setAttribute('rotation', '90 90 90'); component.isRecording = true; component.tick(100); el.setAttribute('position', '2 2 2'); el.setAttribute('rotation', '0 0 0'); component.tick(200); assert.equal(component.recordedPoses.length, 2); assert.shallowDeepEqual(component.recordedPoses[0].position, {x: 1, y: 1, z: 1}); assert.shallowDeepEqual(component.recordedPoses[0].rotation, {x: 90, y: 90, z: 90}); assert.equal(component.recordedPoses[0].timestamp, 100); assert.shallowDeepEqual(component.recordedPoses[1].position, {x: 2, y: 2, z: 2}); assert.shallowDeepEqual(component.recordedPoses[1].rotation, {x: 0, y: 0, z: 0}); assert.equal(component.recordedPoses[1].timestamp, 200); }); test('does not record pose if not recording', function () { assert.equal(component.recordedPoses.length, 0); component.isRecording = false; component.tick(100); assert.equal(component.recordedPoses.length, 0); }); }); suite('recordEvent', function () { test('records axismove', function (done) { assert.equal(component.recordedEvents.length, 0); component.tick(100); component.isRecording = true; el.emit('axismove', {id: 'foo', axis: {x: 1, y: 1}, changed: [true, true]}); setTimeout(() => { assert.equal(component.recordedEvents.length, 1); assert.equal(component.recordedEvents[0].name, 'axismove'); assert.shallowDeepEqual(component.recordedEvents[0].detail, { id: 'foo', axis: {x: 1, y: 1}, changed: [true, true] }); assert.equal(component.recordedEvents[0].timestamp, 100); done(); }); }); test('records buttonchanged', function (done) { assert.equal(component.recordedEvents.length, 0); component.tick(100); component.isRecording = true; el.emit('buttonchanged', {id: 'foo', state: {pressed: true}}); setTimeout(() => { assert.equal(component.recordedEvents.length, 1); assert.equal(component.recordedEvents[0].name, 'buttonchanged'); assert.shallowDeepEqual(component.recordedEvents[0].detail, {id: 'foo', state: {pressed: true}}); assert.equal(component.recordedEvents[0].timestamp, 100); done(); }); }); test('records buttonup', function (done) { assert.equal(component.recordedEvents.length, 0); component.tick(100); component.isRecording = true; el.emit('buttonup', {id: 'foo', state: {pressed: true}}); setTimeout(() => { assert.equal(component.recordedEvents.length, 1); assert.equal(component.recordedEvents[0].name, 'buttonup'); assert.shallowDeepEqual(component.recordedEvents[0].detail, {id: 'foo', state: {pressed: true}}); assert.equal(component.recordedEvents[0].timestamp, 100); done(); }); }); test('records buttondown', function (done) { assert.equal(component.recordedEvents.length, 0); component.tick(100); component.isRecording = true; el.emit('buttondown', {id: 'foo', state: {pressed: true}}); setTimeout(() => { assert.equal(component.recordedEvents.length, 1); assert.equal(component.recordedEvents[0].name, 'buttondown'); assert.shallowDeepEqual(component.recordedEvents[0].detail, {id: 'foo', state: {pressed: true}}); assert.equal(component.recordedEvents[0].timestamp, 100); done(); }); }); test('records touchstart', function (done) { assert.equal(component.recordedEvents.length, 0); component.tick(100); component.isRecording = true; el.emit('touchstart', {id: 'foo', state: {pressed: true}}); setTimeout(() => { assert.equal(component.recordedEvents.length, 1); assert.equal(component.recordedEvents[0].name, 'touchstart'); assert.shallowDeepEqual(component.recordedEvents[0].detail, {id: 'foo', state: {pressed: true}}); assert.equal(component.recordedEvents[0].timestamp, 100); done(); }); }); test('records touchend', function (done) { assert.equal(component.recordedEvents.length, 0); component.tick(100); component.isRecording = true; el.emit('touchend', {id: 'foo', state: {pressed: true}}); setTimeout(() => { assert.equal(component.recordedEvents.length, 1); assert.equal(component.recordedEvents[0].name, 'touchend'); assert.shallowDeepEqual(component.recordedEvents[0].detail, {id: 'foo', state: {pressed: true}}); assert.equal(component.recordedEvents[0].timestamp, 100); done(); }); }); }); suite('startRecording', function () { test('starts recording', function () { assert.notOk(component.isRecording); component.startRecording(); assert.ok(component.isRecording); }); }); suite('stopRecording', function () { test('stops recording', function () { component.isRecording = true; component.stopRecording(); assert.notOk(component.isRecording); }); }); }); suite('motion-capture-replayer', function () { var component; var el; setup(function (done) { el = helpers.entityFactory(); el.addEventListener('componentinitialized', evt => { if (evt.detail.name !== 'motion-capture-replayer') { return; } component = el.components['motion-capture-replayer']; done(); }); el.setAttribute('motion-capture-replayer', 'loop: false'); }); test('plays poses', function () { assert.shallowDeepEqual(el.getAttribute('position'), {x: 0, y: 0, z: 0}); assert.shallowDeepEqual(el.getAttribute('rotation'), {x: 0, y: 0, z: 0}); component.startReplayingPoses([ {timestamp: 100, position: '1 1 1', rotation: '90 90 90'}, {timestamp: 200, position: '2 2 2', rotation: '60 60 60'}, {timestamp: 250, position: '3 3 3', rotation: '30 30 30'} ]); component.tick(150, 50); assert.shallowDeepEqual(el.getAttribute('position'), {x: 1, y: 1, z: 1}); assert.shallowDeepEqual(el.getAttribute('rotation'), {x: 90, y: 90, z: 90}); component.tick(200, 50); assert.shallowDeepEqual(el.getAttribute('position'), {x: 2, y: 2, z: 2}); assert.shallowDeepEqual(el.getAttribute('rotation'), {x: 60, y: 60, z: 60}); component.tick(300, 100); assert.shallowDeepEqual(el.getAttribute('position'), {x: 3, y: 3, z: 3}); assert.shallowDeepEqual(el.getAttribute('rotation'), {x: 30, y: 30, z: 30}); }); test('plays events', function (done) { el.addEventListener('buttondown', function (evt) { assert.equal(evt.detail.id, 'foo'); assert.ok(evt.detail.state); setTimeout(() => { component.tick(200, 100); }); }); el.addEventListener('axismove', function (evt) { assert.equal(evt.detail.id, 'bar'); assert.equal(evt.detail.axis.x, 1); assert.equal(evt.detail.axis.y, 1); setTimeout(() => { component.tick(250, 50); }); }); el.addEventListener('touchend', function (evt) { assert.equal(evt.detail.id, 'baz'); assert.ok(evt.detail.state); done(); }); component.startReplayingEvents([ {timestamp: 100, name: 'buttondown', detail: {id: 'foo', state: {pressed: true}}}, {timestamp: 200, name: 'axismove', detail: {id: 'bar', axis: {x: 1, y: 1}}}, {timestamp: 250, name: 'touchend', detail: {id: 'baz', state: {pressed: true}}} ]); component.tick(150, 50); }); }); suite('motion-capture-replayer system', function () { var el; setup(function (done) { el = helpers.entityFactory(); el.addEventListener('componentinitialized', evt => { if (evt.detail.name !== 'motion-capture-replayer') { return; } component = el.components['motion-capture-replayer']; setTimeout(() => { done(); }, 50); }); el.setAttribute('motion-capture-replayer', 'loop: false'); }); test('injects tracked-controls', function (done) { el.components['motion-capture-replayer'].startReplaying({ gamepad: {id: 'OpenVR Controller', index: 1, hand: 'left'}, poses: [{timestamp: 100, position: '1 1 1', rotation: '90 90 90'}], events: [] }); assert.equal(el.sceneEl.systems['motion-capture-replayer'].gamepads.length, 1); assert.equal(el.sceneEl.systems['tracked-controls'].controllers.length, 0); el.sceneEl.addEventListener('controllersupdated', () => { assert.equal(el.sceneEl.systems['tracked-controls'].controllers.length, 2); assert.equal(el.sceneEl.systems['tracked-controls'].controllers[1].id, 'OpenVR Controller'); done(); }); el.sceneEl.systems['motion-capture-replayer'].updateControllerList(); }); });