/** * Scene Superset - The apiScene properties get moved into the Scene object itself, and then the instance is * created * @param graphics * @param apiScene GameLib.D3.API.Scene * @constructor */ GameLib.D3.Scene = function ( graphics, apiScene ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); if (GameLib.Utils.UndefinedOrNull(apiScene)) { apiScene = {}; } if (apiScene instanceof GameLib.D3.Scene) { return apiScene; } GameLib.D3.API.Scene.call( this, apiScene.id, apiScene.name, apiScene.meshes, apiScene.lights, apiScene.textures, apiScene.materials, apiScene.images, apiScene.fog, apiScene.renderCamera, apiScene.showGrid, apiScene.showAxis, apiScene.gridSize, apiScene.gridColor, apiScene.parentEntity ); this.meshes = this.meshes.map( function(apiMesh) { if (apiMesh instanceof GameLib.D3.API.Mesh) { apiMesh.parentScene = this; return new GameLib.D3.Mesh( this.graphics, apiMesh ); } else { return apiMesh; } }.bind(this) ); this.lights = this.lights.map( function(apiLight) { if (apiLight instanceof GameLib.D3.API.Light) { return new GameLib.D3.Light( this.graphics, apiLight ); } else { return apiLight; } }.bind(this) ); this.textures = this.textures.map( function(apiTexture) { if (apiTexture instanceof GameLib.D3.API.Texture) { var texture = new GameLib.D3.Texture( this.graphics, apiTexture ); return texture; } else { return apiTexture; } }.bind(this) ); this.materials = this.materials.map( function(apiMaterial) { if (apiMaterial instanceof GameLib.D3.API.Material) { var material = new GameLib.D3.Material( this.graphics, apiMaterial ); return material; } else { return apiMaterial; } }.bind(this) ); this.images = this.images.map( function(apiImage) { if (apiImage instanceof GameLib.API.Image) { var image = new GameLib.Image( this.graphics, apiImage ); return image; } else { return apiImage; } }.bind(this) ); if (this.fog instanceof GameLib.D3.API.Fog) { this.fog = new GameLib.D3.Fog( this.graphics, this.fog ) } if (this.renderCamera instanceof GameLib.D3.API.Camera) { this.renderCamera = new GameLib.D3.Camera( this.graphics, this.renderCamera ) } if (this.gridColor instanceof GameLib.API.Color) { this.gridColor = new GameLib.Color( this.graphics, this.gridColor, this ) } /** * Runtime scenes have helpers (just used to store which helper belongs to which scene) * @type {Array} */ this.helpers = []; this.clones = []; this.grid = []; this.axis = []; this.storeClones = false; GameLib.Component.call( this, { 'meshes' : [GameLib.D3.Mesh], 'lights' : [GameLib.D3.Light], 'textures' : [GameLib.D3.Texture], 'materials' : [GameLib.D3.Material], 'images' : [GameLib.Image], 'fog' : GameLib.D3.Fog, 'renderCamera' : GameLib.D3.Camera } ); }; GameLib.D3.Scene.prototype = Object.create(GameLib.D3.API.Scene.prototype); GameLib.D3.Scene.prototype.constructor = GameLib.D3.Scene; /** * Creates an instance scene * @returns {THREE.Scene} */ GameLib.D3.Scene.prototype.createInstance = function() { this.instance = new THREE.Scene(); this.instance.name = this.name; if (this.fog && this.fog.instance) { this.instance.fog = this.fog.instance; } this.meshes.map( function(mesh) { if (GameLib.Utils.UndefinedOrNull(mesh)) { throw new Error('no mesh'); } if (GameLib.Utils.UndefinedOrNull(mesh.instance)) { throw new Error('no mesh instance'); } this.instance.add(mesh.instance); mesh.parentScene = this; }.bind(this) ); this.lights.map( function(light) { if (GameLib.Utils.UndefinedOrNull(light)) { throw new Error('no light'); } if (GameLib.Utils.UndefinedOrNull(light.instance)) { throw new Error('no light instance'); } this.instance.add(light.instance); light.parentScene = this; }.bind(this) ); if (this.showGrid) { this.drawGrid(); } if (this.showAxis) { this.drawAxis(); } GameLib.Component.prototype.createInstance.call(this); }; GameLib.D3.Scene.prototype.updateInstance = function(property) { if (property === 'name') { this.instance.name = this.name; return; } if (this.fog && this.fog.instance !== this.instance.fog) { this.instance.fog = this.fog.instance; } /** * Add missing meshes */ this.meshes.map( function(mesh) { if (this.instance.children.indexOf(mesh.instance === -1)) { this.instance.add(mesh.instance); } }.bind(this) ); /** * Add missing lights */ this.lights.map( function(light) { if (this.instance.children.indexOf(light.instance) === -1) { this.instance.add(light.instance); } }.bind(this) ); /** * Remove extra meshes and lights */ this.instance.children.map( function(instanceObject) { var instanceMeshes = this.meshes.map( function(mesh) { return mesh.instance; } ); var instanceLights = this.lights.map( function(light) { return light.instance; } ); if ( ( instanceObject instanceof THREE.Mesh || instanceObject instanceof THREE.Light ) && ( instanceLights.indexOf(instanceObject) === -1 && instanceMeshes.indexOf(instanceObject) === -1 ) ) { this.instance.remove(instanceObject); } }.bind(this) ); if ( property === 'showGrid' || property === 'gridSize' || property === 'gridColor' ) { if (this.showGrid) { this.drawGrid(); } else { this.removeGrid(); } } if (property === 'showAxis') { if (this.showAxis) { this.drawAxis(); } else { this.removeAxis(); } } }; /** * Converts a GameLib.D3.Scene to a GameLib.D3.API.Scene * @returns {GameLib.D3.API.Scene} */ GameLib.D3.Scene.prototype.toApiObject = function() { var apiMeshes = this.meshes.reduce( function(result, mesh) { /** * Do not store any cloned meshes */ if ((this.clones.indexOf(mesh) === -1) || this.storeClones) { result.push(GameLib.Utils.IdOrNull(mesh)); } return result; }.bind(this), [] ); var apiLights = this.lights.reduce( function(result, light) { /** * Do not store any cloned lights */ if (this.clones.indexOf(light) === -1 || this.storeClones) { result.push(GameLib.Utils.IdOrNull(light)); } return result; }.bind(this), [] ); var apiTextures = this.textures.map( function(texture) { return GameLib.Utils.IdOrNull(texture); } ); var apiMaterials = this.materials.map( function(material) { return GameLib.Utils.IdOrNull(material); } ); var apiImages = this.images.map( function(image) { return GameLib.Utils.IdOrNull(image); } ); return new GameLib.D3.API.Scene( this.id, this.name, apiMeshes, apiLights, apiTextures, apiMaterials, apiImages, GameLib.Utils.IdOrNull(this.fog), GameLib.Utils.IdOrNull(this.renderCamera), this.showGrid, this.showAxis, this.gridSize, this.gridColor.toApiObject(), GameLib.Utils.IdOrNull(this.parentEntity) ); }; /** * Converts a scene Object to a GameLib.D3.Scene object * @param graphics GameLib.GraphicsRuntime * @param objectScene Object * @returns {GameLib.D3.Scene} * @constructor */ GameLib.D3.Scene.FromObject = function( graphics, objectScene ) { var apiScene = GameLib.D3.API.Scene.FromObject(objectScene); return new GameLib.D3.Scene( graphics, apiScene ); }; /** * Adds a mesh to the scene * @param object GameLib.D3.Mesh */ GameLib.D3.Scene.prototype.addObject = function(object) { if (object instanceof GameLib.D3.Mesh) { if (this.meshes.indexOf(object) === -1) { this.meshes.push(object); } } else if (object instanceof GameLib.D3.API.Mesh) { object = new GameLib.D3.Mesh( this.graphics, object ); this.meshes.push(object); } if (object instanceof GameLib.D3.Light) { if (this.lights.indexOf(object) === -1) { this.lights.push(object); } } else if (object instanceof GameLib.D3.API.Light) { object = new GameLib.D3.Light( this.graphics, object ); this.lights.push(object); } object.parentScene = this; if ( this.instance && object.instance ) { if (this.instance.children.indexOf(object.instance) === -1) { this.instance.add(object.instance); } } }; GameLib.D3.Scene.prototype.addClone = function(component) { if (component instanceof GameLib.D3.Mesh || component instanceof GameLib.D3.Light ) { if (this.instance && component.instance) { this.instance.add(component.instance); } GameLib.Utils.PushUnique(this.clones, component); component.parentScene = this; } }; /** * * @param object */ GameLib.D3.Scene.prototype.removeObject = function(object) { var index = -1; if (object instanceof GameLib.D3.Mesh) { index = this.meshes.indexOf(object); if (index !== -1) { this.meshes.splice(index, 1); } index = this.clones.indexOf(object); if (index !== -1) { this.clones.splice(index, 1); } } else if (object instanceof GameLib.D3.Light) { index = this.lights.indexOf(object); if (index !== -1) { this.lights.splice(index, 1); } index = this.clones.indexOf(object); if (index !== -1) { this.clones.splice(index, 1); } } else { console.warn('Cannot remove this object - what is this ?' + object.toString()); return; } if (this.instance.children.indexOf(object.instance) !== -1) { this.instance.remove(object.instance); } else { console.warn('no scene instance'); } if (object.parentScene === this) { object.parentScene = null; } // this.buildIdToObject(); }; GameLib.D3.Scene.prototype.drawGrid = function() { this.removeGrid(); var lineMaterial = new THREE.LineBasicMaterial({ color: this.gridColor.toHex(), linewidth: 1 }); for (var y = -this.gridSize; y <= this.gridSize; y += 1) { var Xgeometry = new THREE.Geometry(); Xgeometry.vertices.push( new THREE.Vector3( y, 0, this.gridSize * -1 ), new THREE.Vector3( y, 0, this.gridSize ) ); var lineX = new THREE.Line(Xgeometry, lineMaterial); this.instance.add(lineX); this.grid.push(lineX); var Ygeometry = new THREE.Geometry(); Ygeometry.vertices.push( new THREE.Vector3( this.gridSize * -1 , 0, y ), new THREE.Vector3( this.gridSize, 0, y ) ); var lineY = new THREE.Line(Ygeometry, lineMaterial); this.instance.add(lineY); this.grid.push(lineY); } }; GameLib.D3.Scene.prototype.removeGrid = function() { this.grid.map( function(object) { this.instance.remove(object); }.bind(this) ); }; GameLib.D3.Scene.prototype.drawAxis = function() { this.removeAxis(); var Xmaterial = new THREE.LineBasicMaterial({ color: 0xff0000, linewidth: 2 }); var Xgeometry = new THREE.Geometry(); Xgeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 100, 0, 0 ) ); var lineX = new THREE.Line(Xgeometry, Xmaterial); this.instance.add(lineX); this.axis.push(lineX); var Ymaterial = new THREE.LineBasicMaterial({ color: 0x00ff00, linewidth: 2 }); var Ygeometry = new THREE.Geometry(); Ygeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 100, 0 ) ); var lineY = new THREE.Line(Ygeometry, Ymaterial); this.instance.add(lineY); this.axis.push(lineY); var Zmaterial = new THREE.LineBasicMaterial({ color: 0x0000ff, linewidth: 2 }); var Zgeometry = new THREE.Geometry(); Zgeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 100 ) ); var lineZ = new THREE.Line(Zgeometry, Zmaterial); this.instance.add(lineZ); this.axis.push(lineZ); }; GameLib.D3.Scene.prototype.removeAxis = function() { this.axis.map( function(object) { this.instance.remove(object); }.bind(this) ); };