diff --git a/dist/aframe-stereo-component.js b/dist/aframe-stereo-component.js index fff8f8c..679722e 100644 --- a/dist/aframe-stereo-component.js +++ b/dist/aframe-stereo-component.js @@ -139,48 +139,35 @@ object3D.rotation.y = Math.PI / 2; - // If left eye is set, and the split is horizontal, take the left half of the video texture. If the split - // is set to vertical, take the top/upper half of the video texture. - - if (this.data.eye === "left") { - var uvs = geometry.faceVertexUvs[ 0 ]; - var axis = this.data.split === "vertical" ? "y" : "x"; - for (var i = 0; i < uvs.length; i++) { - for (var j = 0; j < 3; j++) { - if (axis == "x") { - uvs[ i ][ j ][ axis ] *= 0.5; - } - else { - uvs[ i ][ j ][ axis ] *= 0.5; - uvs[ i ][ j ][ axis ] += 0.5; - } - } - } - } - // If right eye is set, and the split is horizontal, take the right half of the video texture. If the split - // is set to vertical, take the bottom/lower half of the video texture. - - if (this.data.eye === "right") { - var uvs = geometry.faceVertexUvs[ 0 ]; - var axis = this.data.split === "vertical" ? "y" : "x"; - for (var i = 0; i < uvs.length; i++) { - for (var j = 0; j < 3; j++) { - if (axis == "x") { - uvs[ i ][ j ][ axis ] *= 0.5; - uvs[ i ][ j ][ axis ] += 0.5; - } - else { - uvs[ i ][ j ][ axis ] *= 0.5; - } - } - } - } + // Calculate texture offset and repeat and modify UV's + // (cannot use in AFrame material params, since mappings are shared when pointing to the same texture, + // thus, one eye overrides the other) -> https://stackoverflow.com/questions/16976365/two-meshes-same-texture-different-offset + + var axis = this.data.split === 'horizontal' ? 'y' : 'x'; + + // !!! NOTE THAT UV texture coordinates, start at the bottom left point of the texture, so y axis coordinates for left eye on horizontal split + // are 0.5 - 1.0, and for the right eye are 0.0 - 0.5 (they are swapped from THREE.js 'y' axis logic) + + var offset = this.data.eye === 'left' ? (axis === 'y' ? {x: 0, y: 0} : {x: 0, y: 0.5}) : (axis === 'y' ? {x: 0.5, y: 0} : {x: 0, y: 0}); + + var repeat = axis === 'y' ? {x: 0.5, y: 1} : {x: 1, y: 0.5}; + + var uvAttribute = geometry.attributes.uv; + + for (var i = 0; i < uvAttribute.count; i++ ) { + var u = uvAttribute.getX(i)*repeat.x + offset.x; + var v = uvAttribute.getY(i)*repeat.y + offset.y; + + uvAttribute.setXY(i, u, v); + + } + + // Needed in BufferGeometry to update UVs - // As AFrame 0.2.0 builds bufferspheres from sphere entities, transform - // into buffergeometry for coherence + uvAttribute.needsUpdate = true - object3D.geometry = new THREE.BufferGeometry().fromGeometry(geometry); + object3D.geometry = geometry } else{ diff --git a/dist/aframe-stereo-component.min.js b/dist/aframe-stereo-component.min.js index 55e944e..b746aae 100644 --- a/dist/aframe-stereo-component.min.js +++ b/dist/aframe-stereo-component.min.js @@ -1 +1 @@ -!function(e){function t(a){if(i[a])return i[a].exports;var r=i[a]={exports:{},id:a,loaded:!1};return e[a].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var i={};return t.m=e,t.c=i,t.p="",t(0)}([function(e,t,i){!function(){if(!AFRAME)return void console.error("Component attempted to register before AFRAME was available.");var e={stereo:i(1).stereo_component,stereocam:i(1).stereocam_component};Object.keys(e).forEach(function(t){AFRAME.aframeCore?AFRAME.aframeCore.registerComponent(t,e[t]):AFRAME.registerComponent(t,e[t])})}()},function(e,t){e.exports={stereo_component:{schema:{eye:{type:"string",default:"left"},mode:{type:"string",default:"full"},split:{type:"string",default:"horizontal"},playOnClick:{type:"boolean",default:!0}},init:function(){if(this.video_click_event_added=!1,this.material_is_a_video=!1,null!==this.el.getAttribute("material")&&"src"in this.el.getAttribute("material")&&""!==this.el.getAttribute("material").src){var e=this.el.getAttribute("material").src;"object"==typeof e&&"tagName"in e&&"VIDEO"===e.tagName&&(this.material_is_a_video=!0)}var t=this.el.object3D.children[0],i=[THREE.SphereGeometry,THREE.SphereBufferGeometry,THREE.BufferGeometry],a=i.some(function(e){return t.geometry instanceof e});if(a&&this.material_is_a_video){if("half"===this.data.mode)var r=this.el.getAttribute("geometry"),o=new THREE.SphereGeometry(r.radius||100,r.segmentsWidth||64,r.segmentsHeight||64,Math.PI/2,Math.PI,0,Math.PI);else var r=this.el.getAttribute("geometry"),o=new THREE.SphereGeometry(r.radius||100,r.segmentsWidth||64,r.segmentsHeight||64);if(t.rotation.y=Math.PI/2,"left"===this.data.eye)for(var n=o.faceVertexUvs[0],s="vertical"===this.data.split?"y":"x",l=0;l A-Frame Layer Component - Basic + @@ -19,7 +20,7 @@ - <-- or alternatively --> + diff --git a/examples/basic_video/index.html b/examples/basic_video/index.html index c3cb1e3..7c49244 100644 --- a/examples/basic_video/index.html +++ b/examples/basic_video/index.html @@ -1,40 +1,24 @@ A-Frame Layer Component - Basic + - - - - - - - - - - - - - - + + + + + + + + + diff --git a/examples/build.js b/examples/build.js index 9dcaaa5..95992ae 100644 --- a/examples/build.js +++ b/examples/build.js @@ -1,14 +1,11 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o https://stackoverflow.com/questions/16976365/two-meshes-same-texture-different-offset - // If right eye is set, and the split is horizontal, take the right half of the video texture. If the split - // is set to vertical, take the bottom/lower half of the video texture. + var axis = this.data.split === 'horizontal' ? 'y' : 'x'; - if (this.data.eye === "right") { - var uvs = geometry.faceVertexUvs[ 0 ]; - var axis = this.data.split === "vertical" ? "y" : "x"; - for (var i = 0; i < uvs.length; i++) { - for (var j = 0; j < 3; j++) { - if (axis == "x") { - uvs[ i ][ j ][ axis ] *= 0.5; - uvs[ i ][ j ][ axis ] += 0.5; - } - else { - uvs[ i ][ j ][ axis ] *= 0.5; - } - } - } - } + // !!! NOTE THAT UV texture coordinates, start at the bottom left point of the texture, so y axis coordinates for left eye on horizontal split + // are 0.5 - 1.0, and for the right eye are 0.0 - 0.5 (they are swapped from THREE.js 'y' axis logic) + + var offset = this.data.eye === 'left' ? (axis === 'y' ? {x: 0, y: 0} : {x: 0, y: 0.5}) : (axis === 'y' ? {x: 0.5, y: 0} : {x: 0, y: 0}); + + var repeat = axis === 'y' ? {x: 0.5, y: 1} : {x: 1, y: 0.5}; + + var uvAttribute = geometry.attributes.uv; - // As AFrame 0.2.0 builds bufferspheres from sphere entities, transform - // into buffergeometry for coherence + for (var i = 0; i < uvAttribute.count; i++ ) { + var u = uvAttribute.getX(i)*repeat.x + offset.x; + var v = uvAttribute.getY(i)*repeat.y + offset.y; - object3D.geometry = new THREE.BufferGeometry().fromGeometry(geometry); + uvAttribute.setXY(i, u, v); + + } + + // Needed in BufferGeometry to update UVs + + uvAttribute.needsUpdate = true + + object3D.geometry = geometry } else{ @@ -151,7 +136,7 @@ module.exports = { // If this value is false, it means that (a) this is a video on a sphere [see init method] // and (b) of course, tick is not added - if(!this.video_click_event_added){ + if(!this.video_click_event_added && this.data.playOnClick){ if(typeof(this.el.sceneEl.canvas) !== 'undefined'){ // Get video DOM @@ -228,80772 +213,4 @@ module.exports = { } }; -},{}],3:[function(require,module,exports){ -(function (global){ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.AFRAME = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 -} - -function byteLength (b64) { - // base64 is 4/3 + up to two characters of the original data - return b64.length * 3 / 4 - placeHoldersCount(b64) -} - -function toByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - var len = b64.length - placeHolders = placeHoldersCount(b64) - - arr = new Arr(len * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len - - var L = 0 - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] - arr[L++] = (tmp >> 16) & 0xFF - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[L++] = tmp & 0xFF - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} - -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var output = '' - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - output += lookup[tmp >> 2] - output += lookup[(tmp << 4) & 0x3F] - output += '==' - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) - output += lookup[tmp >> 10] - output += lookup[(tmp >> 4) & 0x3F] - output += lookup[(tmp << 2) & 0x3F] - output += '=' - } - - parts.push(output) - - return parts.join('') -} - -},{}],4:[function(_dereq_,module,exports){ -'use strict'; -// For more information about browser field, check out the browser field at https://github.com/substack/browserify-handbook#browser-field. - -module.exports = { - // Create a tag with optional data attributes - createLink: function(href, attributes) { - var head = document.head || document.getElementsByTagName('head')[0]; - var link = document.createElement('link'); - - link.href = href; - link.rel = 'stylesheet'; - - for (var key in attributes) { - if ( ! attributes.hasOwnProperty(key)) { - continue; - } - var value = attributes[key]; - link.setAttribute('data-' + key, value); - } - - head.appendChild(link); - }, - // Create a