CameraHelper.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. * @author Mugen87 / https://github.com/Mugen87
  4. *
  5. * - shows frustum, line of sight and up of the camera
  6. * - suitable for fast updates
  7. * - based on frustum visualization in lightgl.js shadowmap example
  8. * http://evanw.github.com/lightgl.js/tests/shadowmap.html
  9. */
  10. import { Camera } from '../cameras/Camera.js';
  11. import { Vector3 } from '../math/Vector3.js';
  12. import { LineSegments } from '../objects/LineSegments.js';
  13. import { Color } from '../math/Color.js';
  14. import { FaceColors } from '../constants.js';
  15. import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
  16. import { BufferGeometry } from '../core/BufferGeometry.js';
  17. import { Float32BufferAttribute } from '../core/BufferAttribute.js';
  18. var _vector = new Vector3();
  19. var _camera = new Camera();
  20. function CameraHelper( camera ) {
  21. var geometry = new BufferGeometry();
  22. var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );
  23. var vertices = [];
  24. var colors = [];
  25. var pointMap = {};
  26. // colors
  27. var colorFrustum = new Color( 0xffaa00 );
  28. var colorCone = new Color( 0xff0000 );
  29. var colorUp = new Color( 0x00aaff );
  30. var colorTarget = new Color( 0xffffff );
  31. var colorCross = new Color( 0x333333 );
  32. // near
  33. addLine( 'n1', 'n2', colorFrustum );
  34. addLine( 'n2', 'n4', colorFrustum );
  35. addLine( 'n4', 'n3', colorFrustum );
  36. addLine( 'n3', 'n1', colorFrustum );
  37. // far
  38. addLine( 'f1', 'f2', colorFrustum );
  39. addLine( 'f2', 'f4', colorFrustum );
  40. addLine( 'f4', 'f3', colorFrustum );
  41. addLine( 'f3', 'f1', colorFrustum );
  42. // sides
  43. addLine( 'n1', 'f1', colorFrustum );
  44. addLine( 'n2', 'f2', colorFrustum );
  45. addLine( 'n3', 'f3', colorFrustum );
  46. addLine( 'n4', 'f4', colorFrustum );
  47. // cone
  48. addLine( 'p', 'n1', colorCone );
  49. addLine( 'p', 'n2', colorCone );
  50. addLine( 'p', 'n3', colorCone );
  51. addLine( 'p', 'n4', colorCone );
  52. // up
  53. addLine( 'u1', 'u2', colorUp );
  54. addLine( 'u2', 'u3', colorUp );
  55. addLine( 'u3', 'u1', colorUp );
  56. // target
  57. addLine( 'c', 't', colorTarget );
  58. addLine( 'p', 'c', colorCross );
  59. // cross
  60. addLine( 'cn1', 'cn2', colorCross );
  61. addLine( 'cn3', 'cn4', colorCross );
  62. addLine( 'cf1', 'cf2', colorCross );
  63. addLine( 'cf3', 'cf4', colorCross );
  64. function addLine( a, b, color ) {
  65. addPoint( a, color );
  66. addPoint( b, color );
  67. }
  68. function addPoint( id, color ) {
  69. vertices.push( 0, 0, 0 );
  70. colors.push( color.r, color.g, color.b );
  71. if ( pointMap[ id ] === undefined ) {
  72. pointMap[ id ] = [];
  73. }
  74. pointMap[ id ].push( ( vertices.length / 3 ) - 1 );
  75. }
  76. geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  77. geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
  78. LineSegments.call( this, geometry, material );
  79. this.camera = camera;
  80. if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();
  81. this.matrix = camera.matrixWorld;
  82. this.matrixAutoUpdate = false;
  83. this.pointMap = pointMap;
  84. this.update();
  85. }
  86. CameraHelper.prototype = Object.create( LineSegments.prototype );
  87. CameraHelper.prototype.constructor = CameraHelper;
  88. CameraHelper.prototype.update = function () {
  89. var geometry = this.geometry;
  90. var pointMap = this.pointMap;
  91. var w = 1, h = 1;
  92. // we need just camera projection matrix inverse
  93. // world matrix must be identity
  94. _camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse );
  95. // center / target
  96. setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 );
  97. setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 );
  98. // near
  99. setPoint( 'n1', pointMap, geometry, _camera, - w, - h, - 1 );
  100. setPoint( 'n2', pointMap, geometry, _camera, w, - h, - 1 );
  101. setPoint( 'n3', pointMap, geometry, _camera, - w, h, - 1 );
  102. setPoint( 'n4', pointMap, geometry, _camera, w, h, - 1 );
  103. // far
  104. setPoint( 'f1', pointMap, geometry, _camera, - w, - h, 1 );
  105. setPoint( 'f2', pointMap, geometry, _camera, w, - h, 1 );
  106. setPoint( 'f3', pointMap, geometry, _camera, - w, h, 1 );
  107. setPoint( 'f4', pointMap, geometry, _camera, w, h, 1 );
  108. // up
  109. setPoint( 'u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, - 1 );
  110. setPoint( 'u2', pointMap, geometry, _camera, - w * 0.7, h * 1.1, - 1 );
  111. setPoint( 'u3', pointMap, geometry, _camera, 0, h * 2, - 1 );
  112. // cross
  113. setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 );
  114. setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 );
  115. setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 );
  116. setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 );
  117. setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 );
  118. setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 );
  119. setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 );
  120. setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 );
  121. geometry.getAttribute( 'position' ).needsUpdate = true;
  122. };
  123. function setPoint( point, pointMap, geometry, camera, x, y, z ) {
  124. _vector.set( x, y, z ).unproject( camera );
  125. var points = pointMap[ point ];
  126. if ( points !== undefined ) {
  127. var position = geometry.getAttribute( 'position' );
  128. for ( var i = 0, l = points.length; i < l; i ++ ) {
  129. position.setXYZ( points[ i ], _vector.x, _vector.y, _vector.z );
  130. }
  131. }
  132. }
  133. export { CameraHelper };