/** * Input parent class * @param graphics R3.D3.Graphics * @param parentObject * @param apiInputFly R3.D3.API.Input.Fly * @constructor */ R3.D3.Input.Fly = function RuntimeEditorInput( graphics, parentObject, apiInputFly ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); if (R3.Utils.UndefinedOrNull(parentObject)) { parentObject = null; } this.parentObject = parentObject; R3.D3.API.Input.Fly.call( this, apiInputFly.id, apiInputFly.name, apiInputFly.domElementId, apiInputFly.camera ); this.mouseUpCallback = this.onMouseUp.bind(this); this.mouseDownCallback = this.onMouseDown.bind(this); this.mouseMoveCallback = this.onMouseMove.bind(this); this.mouseWheelCallback = this.onMouseWheel.bind(this); this.keyDownCallback = this.onKeyDown.bind(this); this.keyUpCallback = this.onKeyUp.bind(this); this.camera = camera; this.canvas.addEventListener('keydown', this.keyDownCallback, false); this.canvas.addEventListener('keyup', this.keyUpCallback, false); this.canvas.addEventListener('mousedown', this.mouseDownCallback, false); this.canvas.addEventListener('mouseup', this.mouseUpCallback, false); this.canvas.addEventListener('mousewheel', this.mouseWheelCallback, false); this.havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document; this.element = document.body; if (this.havePointerLock) { this.element.requestPointerLock = this.element.requestPointerLock || this.element.mozRequestPointerLock || this.element.webkitRequestPointerLock; document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; } /** * Don't create an instance here - since we don't have our camera loaded yet... */ }; R3.D3.Input.Fly.prototype = Object.create(R3.D3.API.Input.Fly.prototype); R3.D3.Input.Fly.prototype.constructor = R3.D3.Input.Fly; R3.D3.Input.Fly.prototype.createInstance = function(update) { //todo }; R3.D3.Input.Fly.prototype.updateInstance = function() { this.instance = this.createInstance(true); }; R3.D3.Input.Fly.prototype.toApiComponent = function() { var apiInputFly = new R3.D3.API.Input.Fly( this.id, this.name, this.domElementId, R3.Utils.IdOrNull(this.camera) ); return apiInputFly; }; R3.D3.Input.Fly.FromObjectComponent = function(graphics, objectComponent) { var apiInputFly = new R3.D3.API.Input.Fly( objectComponent.id, objectComponent.name, objectComponent.domElementId, objectComponent.camera ); return new R3.D3.Input.Fly( graphics, this, apiInputFly ); }; /** * Go forward / backward on mouse wheel * @param event */ R3.D3.Input.Fly.prototype.onMouseWheel = function(event) { this.moveForward = true; this.applyTranslation(event.wheelDelta * 0.001); event.preventDefault(); this.moveForward = false; }; /** * Start rotating the camera on mouse middle button down * @param event */ R3.D3.Input.Fly.prototype.onMouseDown = function(event) { if (event.button == 1) { this.canRotate = true; this.canvas.addEventListener('mousemove', this.mouseMoveCallback, false); } }; /** * Stop rotating on middle mouse button down * @param event */ R3.D3.Input.Fly.prototype.onMouseUp = function(event) { if (event.button == 1) { this.canRotate = false; this.canvas.removeEventListener('mousemove', this.mouseMoveCallback); } }; /** * Apply current yaw and pitch to camera */ R3.D3.Input.Fly.prototype.applyRotation = function() { this.camera.rotation.set(this.pitch, this.yaw, 0, "YXZ"); }; /** * Apply current position to camera * @param deltaTime */ R3.D3.Input.Fly.prototype.applyTranslation = function(deltaTime) { var direction = new this.THREE.Vector3(0, 0, -1); var rotation = new this.THREE.Euler(0, 0, 0, "YXZ"); rotation.set(this.pitch, this.yaw, 0, "YXZ"); direction = direction.applyEuler(rotation); var forward = direction.normalize(); var right = forward.cross(new this.THREE.Vector3(0, 1, 0)); if(this.moveForward) { this.camera.position.x += forward.x * (deltaTime * this.flySpeed); this.camera.position.y += forward.y * (deltaTime * this.flySpeed); this.camera.position.z += forward.z * (deltaTime * this.flySpeed); } else if(this.moveBackward) { this.camera.position.x -= forward.x * (deltaTime * this.flySpeed); this.camera.position.y -= forward.y * (deltaTime * this.flySpeed); this.camera.position.z -= forward.z * (deltaTime * this.flySpeed); } if(this.moveLeft) { this.camera.position.x -= right.x * (deltaTime * this.flySpeed); this.camera.position.y -= right.y * (deltaTime * this.flySpeed); this.camera.position.z -= right.z * (deltaTime * this.flySpeed); } else if(this.moveRight) { this.camera.position.x += right.x * (deltaTime * this.flySpeed); this.camera.position.y += right.y * (deltaTime * this.flySpeed); this.camera.position.z += right.z * (deltaTime * this.flySpeed); } if(this.moveUp) { this.camera.position.y += (deltaTime * this.flySpeed); } else if(this.moveDown) { this.camera.position.y -= (deltaTime * this.flySpeed); } }; /** * This update function should be called from the animation function in order to apply the 'frame rate independent' * movement to the camera * @param deltaTime */ R3.D3.Input.Fly.prototype.update = function(deltaTime) { this.applyRotation(); this.applyTranslation(deltaTime); }; /** * Rotate on mouse move * @param event */ R3.D3.Input.Fly.prototype.onMouseMove = function ( event ) { if (this.canRotate) { var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; this.yaw -= movementX * 0.002; this.pitch -= movementY * 0.002; } }; /** * Keyboard controls * @param event */ R3.D3.Input.Fly.prototype.onKeyDown = function ( event ) { switch ( event.keyCode ) { case 87: // w this.moveForward = true; break; case 65: // a this.moveLeft = true; break; case 83: // s this.moveBackward = true; break; case 68: // d this.moveRight = true; break; case 104: // keypad up arrow this.moveUp = true; break; case 98: // keypad down arrow this.moveDown = true; break; } }; /** * Keyboard controls * @param event */ R3.D3.Input.Fly.prototype.onKeyUp = function ( event ) { switch ( event.keyCode ) { case 38: // up case 87: // w this.moveForward = false; break; case 37: // left case 65: // a this.moveLeft = false; break; case 40: // down case 83: // s this.moveBackward = false; break; case 39: // right case 68: // d this.moveRight = false; break; case 104: // keypad up arrow this.moveUp = false; break; case 98: // keypad down arrow this.moveDown = false; break; } };