/** * Scene Superset - The apiScene properties get moved into the Scene object itself, and then the instance is * created * @param graphics * @param progressCallback * @param apiScene GameLib.D3.API.Scene * @param imageFactory * @constructor */ GameLib.D3.Scene = function Scene( graphics, progressCallback, apiScene, imageFactory ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); GameLib.D3.API.Scene.call( this, apiScene.id, apiScene.path, apiScene.name, apiScene.meshes, apiScene.position, apiScene.quaternion, apiScene.scale, apiScene.parentSceneId, apiScene.lights, apiScene.worlds, apiScene.entityManager, apiScene.shapes, apiScene.cameras, apiScene.activeCameraIndex, apiScene.splines ); this.position = new GameLib.Vector3( graphics, this, this.position ); this.quaternion = new GameLib.Quaternion( graphics, this, this.quaternion ); this.scale = new GameLib.Vector3( graphics, this, this.scale ); this.entityManager = new GameLib.EntityManager( this, this.entityManager ); this.progressCallback = progressCallback; this.instance = this.createInstance(); this.imageFactory = imageFactory; this.interestingProperties = [ "cameras", "meshes", "lights", "splines" ]; this.idToObject = {}; this.idToObject[this.id] = this; for (var p = 0; p < this.interestingProperties.length; p++) { property = this.interestingProperties[p]; if (this.hasOwnProperty(property)) { for (var i = 0; i < this[property].length; i++) { var object = this[property][i]; this.idToObject[object.id] = object; } } } this.entityManager.entities.map( function (entity) { this.idToObject[entity.id] = entity; entity.components.map( function(component) { if (component instanceof GameLib.Component) { this.idToObject[component.id] = component; } }.bind(this) ) }.bind(this) ); this.entityManager.linkObjects(this.idToObject); }; GameLib.D3.Scene.prototype = Object.create(GameLib.D3.API.Scene.prototype); GameLib.D3.Scene.prototype.constructor = GameLib.D3.Scene; /** * Creates an instance scene * @returns {GameLib.D3.Scene|THREE.Scene|ApiLib.Scene|*|Scene} */ GameLib.D3.Scene.prototype.createInstance = function() { var instance = new THREE.Scene(); instance.name = this.name; instance.position = this.position.instance; instance.scale = this.scale.instance; instance.quaternion = this.quaternion.instance; for (var im = 0; im < this.meshes.length; im++) { instance.add(this.meshes[im].instance); } for (var l = 0; l < this.lights.length; l++) { instance.add(this.lights[l].instance); } instance.render = true; return instance; }; /** * Converts a GameLib.D3.Scene to a GameLib.D3.API.Scene * @returns {GameLib.D3.API.Scene} */ GameLib.D3.Scene.prototype.toApiScene = function() { var apiMeshes = this.meshes.map( function(mesh) { return mesh.toApiMesh(); } ); var apiLights = this.lights.map( function(light) { return light.toApiLight(); } ); var apiEntityManager = null; if (this.entityManager) { apiEntityManager = this.entityManager.toApiEntityManager(); } var apiCameras = this.cameras.map( function(camera) { return camera.toApiCamera(); } ); var apiSplines = this.splines.map( function(spline) { return spline.toApiSpline(); } ); var apiWorlds = this.worlds.map( function(world) { return world.toApiWorld(); } ); var apiShapes = this.shapes.map( function(shape) { return shape.toApiShape(); } ); return new GameLib.D3.API.Scene( this.id, this.path, this.name, apiMeshes, this.position.toApiVector(), this.quaternion.toApiQuaternion(), this.scale.toApiVector(), this.parentSceneId, apiLights, apiWorlds, apiEntityManager, apiShapes, apiCameras, this.activeCameraIndex, apiSplines ); }; /** * Converts a scene Object to a GameLib.D3.Scene object * @param graphics GameLib.D3.Graphics * @param objectScene Object * @param computeNormals boolean to indicate whether or not to recalculate normals * @param imageFactory GameLib.D3.ImageFactory * @param progressCallback callback * @returns {GameLib.D3.Scene} * @constructor */ GameLib.D3.Scene.FromObjectScene = function( graphics, objectScene, computeNormals, imageFactory, progressCallback ) { var apiScene = new GameLib.D3.API.Scene( objectScene.id, objectScene.path, objectScene.name, objectScene.meshes.map( function (objectMesh) { return GameLib.D3.Mesh.FromObjectMesh( graphics, objectMesh, computeNormals, imageFactory ) } ), new GameLib.API.Vector3( objectScene.position.x, objectScene.position.y, objectScene.position.z ), new GameLib.API.Quaternion( objectScene.quaternion.x, objectScene.quaternion.y, objectScene.quaternion.z, objectScene.quaternion.w, new GameLib.API.Vector3( objectScene.quaternion.axis.x, objectScene.quaternion.axis.y, objectScene.quaternion.axis.z ), objectScene.quaternion.angle ), new GameLib.API.Vector3( objectScene.scale.x, objectScene.scale.y, objectScene.scale.z ), objectScene.parentSceneId, objectScene.lights.map( function (objectLight) { return GameLib.D3.Light.FromObjectLight( graphics, objectLight ) } ), objectScene.worlds.map( function (objectWorld) { return GameLib.D3.World.FromObjectWorld( graphics, objectWorld ); } ), GameLib.EntityManager.FromObjectEntityManager( graphics, objectScene.entityManager ), objectScene.shapes.map( function (objectShape) { return GameLib.D3.Shape.FromObjectShape( graphics, objectShape ); } ), objectScene.cameras.map( function (objectCamera) { return GameLib.D3.Camera.FromObjectCamera( graphics, objectCamera ); } ), objectScene.activeCameraIndex, objectScene.splines.map( function (objectSpline) { return GameLib.D3.Spline.FromObjectSpline( graphics, objectSpline ) } ) ); return new GameLib.D3.Scene( graphics, progressCallback, apiScene, imageFactory ); }; /** * Transforms raw scene data into a GameLib.D3.Scene * @param objectScene Object (as it comes from the API) * @param onLoaded * @param graphics * @param uploadUrl * @param progressCallback * @param computeNormals * @constructor */ GameLib.D3.Scene.LoadScene = function( objectScene, onLoaded, graphics, uploadUrl, progressCallback, computeNormals ) { onLoaded( GameLib.D3.Scene.FromObjectScene( graphics, objectScene, computeNormals, GameLib.D3.ImageFactory( graphics, uploadUrl ), progressCallback ) ); }; /** * Loads a scene directly from the API * @param partialSceneObject Object {path: '', name: ''} * @param onLoaded callback * @param graphics GameLib.D3.Graphics * @param uploadUrl String * @param progressCallback callback * @param apiUrl */ GameLib.D3.Scene.LoadSceneFromApi = function( partialSceneObject, onLoaded, graphics, uploadUrl, progressCallback, apiUrl ) { /** * First check if this is a client or server side request */ if (typeof XMLHttpRequest == 'undefined') { console.warn('implement server side loading from API here'); return onLoaded(null, new Error('not implemented')); } var xhr = new XMLHttpRequest(); xhr.open( 'GET', apiUrl + '/scene/load' + partialSceneObject.path + '/' + partialSceneObject.name ); xhr.onreadystatechange = function(xhr) { return function() { if (xhr.readyState == 4) { var response = JSON.parse(xhr.responseText); if (!response.scene || response.scene.length == 0) { return onLoaded(null, null, new Error('Could not load scene')); } var scene = response.scene[0]; GameLib.D3.Scene.LoadScene(scene, onLoaded, graphics, uploadUrl, progressCallback, true); } } }(xhr); xhr.send(); };