From d6ccae45096b802274c8c44e96b867af7d89bdfd Mon Sep 17 00:00:00 2001 From: Michael Feldstein Date: Tue, 27 Dec 2016 20:08:33 -0800 Subject: [PATCH 1/6] Begin work on camera screenshot --- index.html | 4 +- src/components/screenshot-camera.js | 104 ++++++++++++++++++++++++++++ src/components/ui.js | 2 +- src/index.js | 1 + 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/components/screenshot-camera.js diff --git a/index.html b/index.html index 8ad82f5b9..2b5315649 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ - + @@ -33,11 +33,13 @@ brush if-no-vr-headset="visible: false" paint-controls="hand: left" + screenshot-camera ui> Date: Wed, 28 Dec 2016 08:12:26 -0800 Subject: [PATCH 2/6] Get camera shot working --- index.html | 2 +- src/components/screenshot-camera.js | 38 ++++++++++++++++------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/index.html b/index.html index 2b5315649..f04d76825 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ - + diff --git a/src/components/screenshot-camera.js b/src/components/screenshot-camera.js index 1aa88d503..9bbb37b71 100644 --- a/src/components/screenshot-camera.js +++ b/src/components/screenshot-camera.js @@ -51,11 +51,6 @@ AFRAME.registerComponent('screenshot-camera', { }.bind(this)); this.canvas = document.createElement('canvas') - this.canvas.style.position = 'fixed' - this.canvas.style.backgroundColor = 'red' - this.canvas.style.top = 0; - this.canvas.style.zindex = 10000 - document.body.appendChild(this.canvas) this.canvas.width = width this.canvas.height = height }, @@ -72,17 +67,13 @@ AFRAME.registerComponent('screenshot-camera', { var width = this.data.width var height = this.data.height this.pixels = new Uint8Array(4 * width * height) - debugger - this.sceneEl.renderer.readRenderTargetPixels( - this.renderTarget, - 0, 0, width, height, - this.pixels - ) - var gl = this.sceneEl.renderer.context - console.log(gl.getError()) - var allZero = true - for (var i = 0; i < this.pixels.length; i++) { if (this.pixels[i] != 0) allZero = false} - console.log("All zeros?", allZero) + var renderer = this.sceneEl.renderer + + var _gl = renderer.context + var framebuffer = renderer.properties.get(this.renderTarget).__webglFramebuffer + _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); + _gl.readPixels( 0, 0, width, height, _gl.RGBA,_gl.UNSIGNED_BYTE, this.pixels ); + this.pixels = this.flipPixelsVertically(this.pixels, width, height) this.imageData = new ImageData(new Uint8ClampedArray(this.pixels), width, height) this.canvas.getContext('2d').putImageData(this.imageData, 0, 0) @@ -100,5 +91,18 @@ AFRAME.registerComponent('screenshot-camera', { document.body.removeChild(aEl); }, 1); }, 'image/png'); - } + }, + + flipPixelsVertically: function (pixels, width, height) { + var flippedPixels = pixels.slice(0); + for (var x = 0; x < width; ++x) { + for (var y = 0; y < height; ++y) { + flippedPixels[x * 4 + y * width * 4] = pixels[x * 4 + (height - y) * width * 4]; + flippedPixels[x * 4 + 1 + y * width * 4] = pixels[x * 4 + 1 + (height - y) * width * 4]; + flippedPixels[x * 4 + 2 + y * width * 4] = pixels[x * 4 + 2 + (height - y) * width * 4]; + flippedPixels[x * 4 + 3 + y * width * 4] = pixels[x * 4 + 3 + (height - y) * width * 4]; + } + } + return flippedPixels; + }, }); From 1156832b8e4bde33d1530fb9f03a055533f95ecd Mon Sep 17 00:00:00 2001 From: Michael Feldstein Date: Wed, 28 Dec 2016 08:53:57 -0800 Subject: [PATCH 3/6] Wire up the camera to the clear button temporarily until i get a new button in the model --- src/components/screenshot-camera.js | 17 ++++++++++++++--- src/components/ui.js | 14 ++++++++++++-- src/index.js | 6 ++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/components/screenshot-camera.js b/src/components/screenshot-camera.js index 9bbb37b71..1eb0cc76a 100644 --- a/src/components/screenshot-camera.js +++ b/src/components/screenshot-camera.js @@ -5,7 +5,7 @@ AFRAME.registerComponent('screenshot-camera', { width: {default: 1024, min: 1, max: 2048}, height: {default: 768, min: 1, max: 1516}, brush: {default: 'flat'}, - enabled: { default: true } + enabled: { default: false } }, init: function () { var data = this.data; @@ -41,12 +41,18 @@ AFRAME.registerComponent('screenshot-camera', { this.el.object3D.add(this.screen) this.el.object3D.add(this.camera) - this.el.addEventListener('buttondown', function (evt) { + this.canTakePicture = true + + this.el.addEventListener('triggerchanged', function (evt) { if (!this.data.enabled) { return } - if (evt.detail.id === 1) { + + if (evt.detail.value == 1 && this.canTakePicture) { this.saveNextTick = true + this.canTakePicture = false + } else if (evt.detail.value < 1) { + this.canTakePicture = true } }.bind(this)); @@ -55,7 +61,12 @@ AFRAME.registerComponent('screenshot-camera', { this.canvas.height = height }, + update: function() { + this.screen.visible = this.data.enabled + }, + tick: function(time, timeDelta) { + if (!this.data.enabled) return this.sceneEl.renderer.render(this.scene, this.camera, this.renderTarget, true) if (this.saveNextTick) { this.saveCapture(); diff --git a/src/components/ui.js b/src/components/ui.js index 60ca4e9e3..adfa9398b 100644 --- a/src/components/ui.js +++ b/src/components/ui.js @@ -1,7 +1,7 @@ /* globals AFRAME THREE */ AFRAME.registerComponent('ui', { schema: { brightness: { default: 1.0, max: 1.0, min: 0.0 } }, - dependencies: ['ui-raycaster', 'screenshot-camera'], + dependencies: ['ui-raycaster', 'screenshot-camera', 'brush'], init: function () { var el = this.el; @@ -156,6 +156,7 @@ AFRAME.registerComponent('ui', { } case name === 'clear': { if (!this.pressedObjects[name]) { + this.toggleCaptureCamera(); this.el.sceneEl.systems.brush.clear(); } break; @@ -355,6 +356,14 @@ AFRAME.registerComponent('ui', { this.handEl.setAttribute('brush', 'size', brushSize); }, + toggleCaptureCamera: function() { + var enableScreenshot = !this.handEl.getAttribute('screenshot-camera').enabled + console.log("Will enable screenshot", enableScreenshot) + this.handEl.setAttribute('screenshot-camera', 'enabled', enableScreenshot) + this.handEl.setAttribute('brush', 'enabled', !enableScreenshot) + this.handEl.isInCameraMode = enableScreenshot + }, + handleHover: function () { this.updateHoverObjects(); this.updateMaterials(); @@ -806,7 +815,8 @@ AFRAME.registerComponent('ui', { onIntersectionCleared: function () { this.checkMenuIntersections = false; this.rayEl.setAttribute('visible', false); - this.el.setAttribute('brush', 'enabled', true); + // Only re-enable if we're not in camera mode + this.el.setAttribute('brush', 'enabled', !this.el.isInCameraMode); }, onIntersectedCleared: function (evt) { diff --git a/src/index.js b/src/index.js index 3cda530d4..b18981b00 100644 --- a/src/index.js +++ b/src/index.js @@ -28,3 +28,9 @@ require('./brushes/stamp.js'); require('./brushes/spheres.js'); require('./brushes/cubes.js'); require('./brushes/rainbow.js'); + +var f = function() { + requestAnimationFrame(f) + AFRAME.TWEEN.update() +} +requestAnimationFrame(f) From b97f826241bcb062010ccd55732e2b7d3a6bb487 Mon Sep 17 00:00:00 2001 From: Michael Feldstein Date: Wed, 28 Dec 2016 10:24:06 -0800 Subject: [PATCH 4/6] Use a higher level trigger-mode attribute instead of manually enabling and disabling each component --- index.html | 2 ++ src/components/brush.js | 14 ++++++++++++-- src/components/screenshot-camera.js | 15 ++++++++------- src/components/ui.js | 11 ++++------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/index.html b/index.html index f04d76825..ff9fd9a3f 100644 --- a/index.html +++ b/index.html @@ -34,12 +34,14 @@ if-no-vr-headset="visible: false" paint-controls="hand: left" screenshot-camera + trigger-mode="brush" ui> Date: Wed, 28 Dec 2016 10:34:20 -0800 Subject: [PATCH 5/6] Screenshot camera: remove unnecessary attributes --- src/components/screenshot-camera.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/screenshot-camera.js b/src/components/screenshot-camera.js index 9c046fd90..319231894 100644 --- a/src/components/screenshot-camera.js +++ b/src/components/screenshot-camera.js @@ -1,10 +1,8 @@ /* globals AFRAME THREE */ AFRAME.registerComponent('screenshot-camera', { schema: { - color: {type: 'color', default: '#ef2d5e'}, width: {default: 1024, min: 1, max: 2048}, height: {default: 768, min: 1, max: 1516}, - brush: {default: 'flat'}, }, init: function () { var data = this.data; @@ -14,13 +12,8 @@ AFRAME.registerComponent('screenshot-camera', { this.scene = this.sceneEl.object3D this.renderTarget = new THREE.WebGLRenderTarget(width, height, { - minFilter: THREE.LinearFilter, - magFilter: THREE.LinearFilter, - wrapS: THREE.ClampToEdgeWrapping, - wrapT: THREE.ClampToEdgeWrapping, format: THREE.RGBAFormat, type: THREE.UnsignedByteType, - autoClear: true }) var ratio = width / height; From 4d603b6bfe9451f774204fe8c043f59611e98866 Mon Sep 17 00:00:00 2001 From: Michael Feldstein Date: Wed, 28 Dec 2016 19:56:29 -0800 Subject: [PATCH 6/6] Screenshot Control: remove unneeded code --- src/components/ui.js | 2 +- src/index.js | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/components/ui.js b/src/components/ui.js index eb83fd5a2..2b7f28e5c 100644 --- a/src/components/ui.js +++ b/src/components/ui.js @@ -1,7 +1,7 @@ /* globals AFRAME THREE */ AFRAME.registerComponent('ui', { schema: { brightness: { default: 1.0, max: 1.0, min: 0.0 } }, - dependencies: ['ui-raycaster', 'screenshot-camera', 'brush'], + dependencies: ['ui-raycaster'], init: function () { var el = this.el; diff --git a/src/index.js b/src/index.js index b18981b00..3cda530d4 100644 --- a/src/index.js +++ b/src/index.js @@ -28,9 +28,3 @@ require('./brushes/stamp.js'); require('./brushes/spheres.js'); require('./brushes/cubes.js'); require('./brushes/rainbow.js'); - -var f = function() { - requestAnimationFrame(f) - AFRAME.TWEEN.update() -} -requestAnimationFrame(f)