CSS3DStereoRenderer.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. THREE.CSS3DObject = function ( element ) {
  5. THREE.Object3D.call( this );
  6. this.elementL = element.cloneNode( true );
  7. this.elementL.style.position = 'absolute';
  8. this.elementR = element.cloneNode( true );
  9. this.elementR.style.position = 'absolute';
  10. this.addEventListener( 'removed', function ( event ) {
  11. if ( this.elementL.parentNode !== null ) {
  12. this.elementL.parentNode.removeChild( this.elementL );
  13. }
  14. if ( this.elementR.parentNode !== null ) {
  15. this.elementR.parentNode.removeChild( this.elementR );
  16. }
  17. } );
  18. };
  19. THREE.CSS3DObject.prototype = Object.create( THREE.Object3D.prototype );
  20. THREE.CSS3DObject.prototype.constructor = THREE.CSS3DObject;
  21. THREE.CSS3DSprite = function ( element ) {
  22. THREE.CSS3DObject.call( this, element );
  23. };
  24. THREE.CSS3DSprite.prototype = Object.create( THREE.CSS3DObject.prototype );
  25. THREE.CSS3DSprite.prototype.constructor = THREE.CSS3DSprite;
  26. //
  27. THREE.CSS3DStereoRenderer = function () {
  28. console.log( 'THREE.CSS3DRenderer', THREE.REVISION );
  29. var _width, _height;
  30. var _widthHalf, _heightHalf;
  31. var matrix = new THREE.Matrix4();
  32. var _position = new THREE.Vector3();
  33. var _quaternion = new THREE.Quaternion();
  34. var _scale = new THREE.Vector3();
  35. var _cameraL = new THREE.PerspectiveCamera();
  36. var _cameraR = new THREE.PerspectiveCamera();
  37. var _target = new THREE.Vector3();
  38. this.separation = 6;
  39. this.targetDistance = 500;
  40. //
  41. var domElement = document.createElement( 'div' );
  42. this.domElement = domElement;
  43. //
  44. var domElementL = document.createElement( 'div' );
  45. domElementL.style.display = 'inline-block';
  46. domElementL.style.overflow = 'hidden';
  47. domElementL.style.WebkitTransformStyle = 'preserve-3d';
  48. domElementL.style.MozTransformStyle = 'preserve-3d';
  49. domElementL.style.oTransformStyle = 'preserve-3d';
  50. domElementL.style.transformStyle = 'preserve-3d';
  51. domElement.appendChild( domElementL );
  52. var cameraElementL = document.createElement( 'div' );
  53. cameraElementL.style.WebkitTransformStyle = 'preserve-3d';
  54. cameraElementL.style.MozTransformStyle = 'preserve-3d';
  55. cameraElementL.style.oTransformStyle = 'preserve-3d';
  56. cameraElementL.style.transformStyle = 'preserve-3d';
  57. domElementL.appendChild( cameraElementL );
  58. //
  59. var domElementR = document.createElement( 'div' );
  60. domElementR.style.display = 'inline-block';
  61. domElementR.style.overflow = 'hidden';
  62. domElementR.style.WebkitTransformStyle = 'preserve-3d';
  63. domElementR.style.MozTransformStyle = 'preserve-3d';
  64. domElementR.style.oTransformStyle = 'preserve-3d';
  65. domElementR.style.transformStyle = 'preserve-3d';
  66. domElement.appendChild( domElementR );
  67. var cameraElementR = document.createElement( 'div' );
  68. cameraElementR.style.WebkitTransformStyle = 'preserve-3d';
  69. cameraElementR.style.MozTransformStyle = 'preserve-3d';
  70. cameraElementR.style.oTransformStyle = 'preserve-3d';
  71. cameraElementR.style.transformStyle = 'preserve-3d';
  72. domElementR.appendChild( cameraElementR );
  73. this.setClearColor = function () {
  74. };
  75. this.setSize = function ( width, height ) {
  76. domElement.style.width = width + 'px';
  77. domElement.style.height = height + 'px';
  78. _width = width / 2;
  79. _height = height;
  80. _widthHalf = _width / 2;
  81. _heightHalf = _height / 2;
  82. domElementL.style.width = _width + 'px';
  83. domElementL.style.height = _height + 'px';
  84. cameraElementL.style.width = _width + 'px';
  85. cameraElementL.style.height = _height + 'px';
  86. domElementR.style.width = _width + 'px';
  87. domElementR.style.height = _height + 'px';
  88. cameraElementR.style.width = _width + 'px';
  89. cameraElementR.style.height = _height + 'px';
  90. };
  91. var epsilon = function ( value ) {
  92. return Math.abs( value ) < 0.000001 ? 0 : value;
  93. };
  94. var getCameraCSSMatrix = function ( matrix ) {
  95. var elements = matrix.elements;
  96. return 'matrix3d(' +
  97. epsilon( elements[ 0 ] ) + ',' +
  98. epsilon( - elements[ 1 ] ) + ',' +
  99. epsilon( elements[ 2 ] ) + ',' +
  100. epsilon( elements[ 3 ] ) + ',' +
  101. epsilon( elements[ 4 ] ) + ',' +
  102. epsilon( - elements[ 5 ] ) + ',' +
  103. epsilon( elements[ 6 ] ) + ',' +
  104. epsilon( elements[ 7 ] ) + ',' +
  105. epsilon( elements[ 8 ] ) + ',' +
  106. epsilon( - elements[ 9 ] ) + ',' +
  107. epsilon( elements[ 10 ] ) + ',' +
  108. epsilon( elements[ 11 ] ) + ',' +
  109. epsilon( elements[ 12 ] ) + ',' +
  110. epsilon( - elements[ 13 ] ) + ',' +
  111. epsilon( elements[ 14 ] ) + ',' +
  112. epsilon( elements[ 15 ] ) +
  113. ')';
  114. };
  115. var getObjectCSSMatrix = function ( matrix ) {
  116. var elements = matrix.elements;
  117. return 'translate3d(-50%,-50%,0) matrix3d(' +
  118. epsilon( elements[ 0 ] ) + ',' +
  119. epsilon( elements[ 1 ] ) + ',' +
  120. epsilon( elements[ 2 ] ) + ',' +
  121. epsilon( elements[ 3 ] ) + ',' +
  122. epsilon( - elements[ 4 ] ) + ',' +
  123. epsilon( - elements[ 5 ] ) + ',' +
  124. epsilon( - elements[ 6 ] ) + ',' +
  125. epsilon( - elements[ 7 ] ) + ',' +
  126. epsilon( elements[ 8 ] ) + ',' +
  127. epsilon( elements[ 9 ] ) + ',' +
  128. epsilon( elements[ 10 ] ) + ',' +
  129. epsilon( elements[ 11 ] ) + ',' +
  130. epsilon( elements[ 12 ] ) + ',' +
  131. epsilon( elements[ 13 ] ) + ',' +
  132. epsilon( elements[ 14 ] ) + ',' +
  133. epsilon( elements[ 15 ] ) +
  134. ')';
  135. };
  136. var renderObject = function ( object, camera, cameraElement, side ) {
  137. if ( object instanceof THREE.CSS3DObject ) {
  138. var style;
  139. if ( object instanceof THREE.CSS3DSprite ) {
  140. // http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/
  141. matrix.copy( camera.matrixWorldInverse );
  142. matrix.transpose();
  143. matrix.copyPosition( object.matrixWorld );
  144. matrix.scale( object.scale );
  145. matrix.elements[ 3 ] = 0;
  146. matrix.elements[ 7 ] = 0;
  147. matrix.elements[ 11 ] = 0;
  148. matrix.elements[ 15 ] = 1;
  149. style = getObjectCSSMatrix( matrix );
  150. } else {
  151. style = getObjectCSSMatrix( object.matrixWorld );
  152. }
  153. var element = object[ 'element' + side ];
  154. element.style.WebkitTransform = style;
  155. element.style.MozTransform = style;
  156. element.style.oTransform = style;
  157. element.style.transform = style;
  158. if ( element.parentNode !== cameraElement ) {
  159. cameraElement.appendChild( element );
  160. }
  161. }
  162. for ( var i = 0, l = object.children.length; i < l; i ++ ) {
  163. renderObject( object.children[ i ], camera, cameraElement, side );
  164. }
  165. };
  166. this.render = function ( scene, camera ) {
  167. scene.updateMatrixWorld();
  168. if ( camera.parent === undefined ) camera.updateMatrixWorld();
  169. camera.matrixWorld.decompose( _position, _quaternion, _scale );
  170. _target.set( 0, 0, - this.targetDistance );
  171. _target.applyQuaternion( _quaternion );
  172. _target.add( _position );
  173. var fov = 0.5 / Math.tan( THREE.Math.degToRad( camera.fov * 0.5 ) ) * _height;
  174. // Left
  175. _cameraL.fov = camera.fov;
  176. _cameraL.aspect = 0.5 * camera.aspect;
  177. _cameraL.updateProjectionMatrix();
  178. _cameraL.near = camera.near;
  179. _cameraL.far = camera.far;
  180. _cameraL.position.copy( _position );
  181. _cameraL.translateX( - this.separation );
  182. _cameraL.lookAt( _target );
  183. _cameraL.updateMatrixWorld();
  184. domElementL.style.WebkitPerspective = fov + "px";
  185. domElementL.style.MozPerspective = fov + "px";
  186. domElementL.style.oPerspective = fov + "px";
  187. domElementL.style.perspective = fov + "px";
  188. _cameraL.matrixWorldInverse.getInverse( _cameraL.matrixWorld );
  189. var style = "translate3d(0,0," + fov + "px)" + getCameraCSSMatrix( _cameraL.matrixWorldInverse ) +
  190. " translate3d(" + _widthHalf + "px," + _heightHalf + "px, 0)";
  191. cameraElementL.style.WebkitTransform = style;
  192. cameraElementL.style.MozTransform = style;
  193. cameraElementL.style.oTransform = style;
  194. cameraElementL.style.transform = style;
  195. renderObject( scene, _cameraL, cameraElementL, 'L' );
  196. // Right
  197. _cameraR.projectionMatrix = _cameraL.projectionMatrix;
  198. _cameraR.near = camera.near;
  199. _cameraR.far = camera.far;
  200. _cameraR.position.copy( _position );
  201. _cameraR.translateX( this.separation );
  202. _cameraR.lookAt( _target );
  203. _cameraR.updateMatrixWorld();
  204. domElementR.style.WebkitPerspective = fov + "px";
  205. domElementR.style.MozPerspective = fov + "px";
  206. domElementR.style.oPerspective = fov + "px";
  207. domElementR.style.perspective = fov + "px";
  208. _cameraR.matrixWorldInverse.getInverse( _cameraR.matrixWorld );
  209. var style = "translate3d(0,0," + fov + "px)" + getCameraCSSMatrix( _cameraR.matrixWorldInverse ) +
  210. " translate3d(" + _widthHalf + "px," + _heightHalf + "px, 0)";
  211. cameraElementR.style.WebkitTransform = style;
  212. cameraElementR.style.MozTransform = style;
  213. cameraElementR.style.oTransform = style;
  214. cameraElementR.style.transform = style;
  215. renderObject( scene, _cameraR, cameraElementR, 'R' );
  216. };
  217. };