QuakeCamera.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. * @author alteredq / http://alteredqualia.com/
  4. * @author paulirish / http://paulirish.com/
  5. *
  6. * parameters = {
  7. * fov: <float>,
  8. * aspect: <float>,
  9. * near: <float>,
  10. * far: <float>,
  11. * target: <THREE.Object3D>,
  12. * movementSpeed: <float>,
  13. * lookSpeed: <float>,
  14. * noFly: <bool>,
  15. * lookVertical: <bool>,
  16. * domElement: <HTMLElement>,
  17. * }
  18. */
  19. function bind( scope, fn ) {
  20. return function () {
  21. fn.apply( scope, arguments );
  22. };
  23. }
  24. THREE.QuakeCamera = function ( parameters ) {
  25. THREE.Camera.call( this, parameters.fov, parameters.aspect, parameters.near, parameters.far, parameters.target );
  26. this.movementSpeed = 1.0;
  27. this.lookSpeed = 0.005;
  28. this.noFly = false;
  29. this.lookVertical = true;
  30. this.autoForward = false;
  31. this.domElement = document;
  32. if ( parameters ) {
  33. if ( parameters.movementSpeed !== undefined ) this.movementSpeed = parameters.movementSpeed;
  34. if ( parameters.lookSpeed !== undefined ) this.lookSpeed = parameters.lookSpeed;
  35. if ( parameters.noFly !== undefined ) this.noFly = parameters.noFly;
  36. if ( parameters.lookVertical !== undefined ) this.lookVertical = parameters.lookVertical;
  37. if ( parameters.autoForward !== undefined ) this.autoForward = parameters.autoForward;
  38. if ( parameters.domElement !== undefined ) this.domElement = parameters.domElement;
  39. }
  40. this.mouseX = 0;
  41. this.mouseY = 0;
  42. this.lat = 0;
  43. this.lon = 0;
  44. this.phy = 0;
  45. this.theta = 0;
  46. this.moveForward = false;
  47. this.moveBackward = false;
  48. this.moveLeft = false;
  49. this.moveRight = false;
  50. this.windowHalfX = window.innerWidth / 2;
  51. this.windowHalfY = window.innerHeight / 2;
  52. this.onMouseDown = function ( event ) {
  53. event.preventDefault();
  54. event.stopPropagation();
  55. switch ( event.button ) {
  56. case 0: this.moveForward = true; break;
  57. case 2: this.moveBackward = true; break;
  58. }
  59. };
  60. this.onMouseUp = function ( event ) {
  61. event.preventDefault();
  62. event.stopPropagation();
  63. switch ( event.button ) {
  64. case 0: this.moveForward = false; break;
  65. case 2: this.moveBackward = false; break;
  66. }
  67. };
  68. this.onMouseMove = function (event) {
  69. this.mouseX = event.clientX - this.windowHalfX;
  70. this.mouseY = event.clientY - this.windowHalfY;
  71. };
  72. this.onKeyDown = function ( event ) {
  73. switch( event.keyCode ) {
  74. case 38: /*up*/
  75. case 87: /*W*/ this.moveForward = true; break;
  76. case 37: /*left*/
  77. case 65: /*A*/ this.moveLeft = true; break;
  78. case 40: /*down*/
  79. case 83: /*S*/ this.moveBackward = true; break;
  80. case 39: /*right*/
  81. case 68: /*D*/ this.moveRight = true; break;
  82. }
  83. };
  84. this.onKeyUp = function ( event ) {
  85. switch( event.keyCode ) {
  86. case 38: /*up*/
  87. case 87: /*W*/ this.moveForward = false; break;
  88. case 37: /*left*/
  89. case 65: /*A*/ this.moveLeft = false; break;
  90. case 40: /*down*/
  91. case 83: /*S*/ this.moveBackward = false; break;
  92. case 39: /*right*/
  93. case 68: /*D*/ this.moveRight = false; break;
  94. }
  95. };
  96. this.update = function() {
  97. if ( this.moveForward || this.autoForward ) this.translateZ( - this.movementSpeed, this.noFly );
  98. if ( this.moveBackward ) this.translateZ( this.movementSpeed, this.noFly );
  99. if ( this.moveLeft ) this.translateX( - this.movementSpeed, this.noFly );
  100. if ( this.moveRight ) this.translateX( this.movementSpeed, this.noFly );
  101. this.lon += this.mouseX * this.lookSpeed;
  102. if( this.lookVertical ) this.lat -= this.mouseY * this.lookSpeed;
  103. this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
  104. this.phi = ( 90 - this.lat ) * Math.PI / 180;
  105. this.theta = this.lon * Math.PI / 180;
  106. var targetPosition = this.target.position,
  107. position = this.position;
  108. targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
  109. targetPosition.y = position.y + 100 * Math.cos( this.phi );
  110. targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
  111. this.supr.update.call( this );
  112. };
  113. this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
  114. this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
  115. this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false );
  116. this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false );
  117. this.domElement.addEventListener( 'keydown', bind( this, this.onKeyDown ), false );
  118. this.domElement.addEventListener( 'keyup', bind( this, this.onKeyUp ), false );
  119. };
  120. THREE.QuakeCamera.prototype = new THREE.Camera();
  121. THREE.QuakeCamera.prototype.constructor = THREE.QuakeCamera;
  122. THREE.QuakeCamera.prototype.supr = THREE.Camera.prototype;