/** * GameLib.D3.Camera * @param graphics GameLib.GraphicsRuntime * @param apiCamera GameLib.D3.API.Camera * @constructor */ GameLib.D3.Camera = function( graphics, apiCamera ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); if (GameLib.Utils.UndefinedOrNull(apiCamera)) { apiCamera = {}; } GameLib.D3.API.Camera.call( this, apiCamera.id, apiCamera.name, apiCamera.cameraType, apiCamera.aspect, apiCamera.position, apiCamera.rotation, apiCamera.quaternion, apiCamera.lookAt, apiCamera.parentEntity ); this.position = new GameLib.Vector3( graphics, this.position, this ); this.lookAt = new GameLib.Vector3( graphics, this.lookAt, this ); this.rotation = new GameLib.Vector3( graphics, this.rotation, this ); this.quaternion = new GameLib.Quaternion( graphics, this.quaternion, this ); var linkedObjects = {}; switch (apiCamera.cameraType) { case GameLib.D3.API.Camera.CAMERA_TYPE_CUBE : linkedObjects.renderTarget = GameLib.D3.RenderTarget; break; case GameLib.D3.API.Camera.CAMERA_TYPE_STEREO : linkedObjects.effect = GameLib.D3.Effect; break; default : break; } GameLib.Component.call( this, linkedObjects ); }; GameLib.D3.Camera.prototype = Object.create(GameLib.Component.prototype); GameLib.D3.Camera.prototype.constructor = GameLib.D3.Camera; /** * Creates a camera instance of 'graphics' type (only THREE for now) * @returns {THREE.Camera} */ GameLib.D3.Camera.prototype.createInstance = function() { /** * Not all implementations of camera has a position (Stereo camera gets its position on update) */ if (GameLib.Utils.Defined(this.instance.position)) { this.instance.position.x = this.position.x; this.instance.position.y = this.position.y; this.instance.position.z = this.position.z; } if (GameLib.Utils.Defined(this.instance.rotation)) { this.instance.rotation.x = this.rotation.x; this.instance.rotation.y = this.rotation.y; this.instance.rotation.z = this.rotation.z; } if (GameLib.Utils.Defined(this.instance.quaternion)) { this.instance.quaternion.x = this.quaternion.x; this.instance.quaternion.y = this.quaternion.y; this.instance.quaternion.z = this.quaternion.z; this.instance.quaternion.w = this.quaternion.w; } /** * Not all implementations of camera has aspect ratio, we, however do have an aspect ratio for all our cameras */ if (GameLib.Utils.Defined(this.instance.aspect)) { this.instance.aspect = this.aspect; } /** * Only do lookAt for stereo and cube cameras */ if ( this.cameraType === GameLib.D3.API.Camera.CAMERA_TYPE_STEREO || this.cameraType === GameLib.D3.API.Camera.CAMERA_TYPE_PERSPECTIVE ) { this.instance.lookAt(this.lookAt.instance); } if (GameLib.Utils.Defined(this.instance.updateProjectionMatrix)) { this.instance.updateProjectionMatrix(); } GameLib.Component.prototype.createInstance.call(this); }; /** * Updates the instance with the current state */ GameLib.D3.Camera.prototype.updateInstance = function(property) { if (GameLib.Utils.UndefinedOrNull(property)) { console.warn('no camera property specified for : ' + this.name); } if (property === 'cameraType') { this.remove(); var args = [this.graphics, { id : this.id, name : this.name }]; if (this.cameraType === GameLib.D3.API.Camera.CAMERA_TYPE_STEREO) { GameLib.D3.Camera.Stereo.apply(this, args); } if (this.cameraType === GameLib.D3.API.Camera.CAMERA_TYPE_CUBE) { GameLib.D3.Camera.Cube.apply(this, args); } if (this.cameraType === GameLib.D3.API.Camera.CAMERA_TYPE_PERSPECTIVE) { GameLib.D3.Camera.Perspective.apply(this, args); } if (this.cameraType === GameLib.D3.API.Camera.CAMERA_TYPE_ORTHOGRAPHIC) { GameLib.D3.Camera.Orthographic.apply(this, args); } return; } if (property === 'aspect') { if (GameLib.Utils.Defined(this.instance.aspect)) { this.instance.aspect = this.aspect; if (GameLib.Utils.Defined(this.instance.updateProjectionMatrix)) { this.instance.updateProjectionMatrix(); } } else { console.warn('updating the aspect ratio of this type of camera has no effect.'); } return; } if (property === 'position') { this.instance.position.x = this.position.x; this.instance.position.y = this.position.y; this.instance.position.z = this.position.z; if (GameLib.Utils.Defined(this.instance.updateProjectionMatrix)) { this.instance.updateProjectionMatrix(); } return; } if (property === 'rotation') { this.instance.rotation.x = this.rotation.x; this.instance.rotation.y = this.rotation.y; this.instance.rotation.z = this.rotation.z; if (GameLib.Utils.Defined(this.instance.updateProjectionMatrix)) { this.instance.updateProjectionMatrix(); } return; } if (property === 'quaternion') { console.log('todo: update quaternion'); // return; // if (GameLib.Utils.Defined(this.instance.updateProjectionMatrix)) { // this.instance.updateProjectionMatrix(); // } return; } if (property === 'lookAt') { this.lookAt.instance.x = this.lookAt.x; this.lookAt.instance.y = this.lookAt.y; this.lookAt.instance.z = this.lookAt.z; if (GameLib.Utils.Defined(this.instance.lookAt)) { this.instance.lookAt(this.lookAt.instance); } if (GameLib.Utils.Defined(this.instance.updateProjectionMatrix)) { this.instance.updateProjectionMatrix(); } return; } GameLib.Component.prototype.updateInstance.call(this, property); }; /** * Resize default * @param width * @param height */ // GameLib.D3.Camera.prototype.resize = function(width, height) { // camera.aspect = width / height; // camera.updateInstance(); // }; /** * Converts a GameLib.D3.Camera to a new GameLib.D3.API.Camera * @returns {GameLib.D3.API.Camera} */ GameLib.D3.Camera.prototype.toApiObject = function() { return new GameLib.D3.API.Camera( this.id, this.name, this.cameraType, this.aspect, this.position.toApiObject(), this.lookAt.toApiObject(), GameLib.Utils.IdOrNull(this.parentEntity) ); }; GameLib.D3.Camera.prototype.updateFromInstance = function() { this.aspect = this.instance.aspect; this.position.x = this.instance.position.x; this.position.y = this.instance.position.y; this.position.z = this.instance.position.z; if (this.instance.target) { this.lookAt.x = this.instance.target.position.x; this.lookAt.y = this.instance.target.position.y; this.lookAt.z = this.instance.target.position.z; } else { console.warn('todo: update lookAt somehow...'); } };