/** * Stats component for displaying some render statistics (framerate, memory consumption, etc) * @param gui * @param id * @param name * @param domElement * @param objects * @param parentEntity * @constructor */ GameLib.GUI = function( gui, id, name, domElement, objects, parentEntity ) { if (GameLib.Utils.UndefinedOrNull(gui)) { throw new Error('Need GUI object') } this.gui = gui; /** * Add some GUI behaviour */ this.gui.prototype.removeEmtpyFolders = function() { for (var property in this.__folders) { if (this.__folders.hasOwnProperty(property)){ var folder = this.__folders[property]; if (folder.__listening.length === 0) { folder.close(); this.__ul.removeChild(folder.domElement.parentNode); delete this.__folders[property]; this.onResize(); } } } }; this.gui.prototype.removeAllFolders = function() { for (var property in this.__folders) { if (this.__folders.hasOwnProperty(property)){ var folder = this.__folders[property]; folder.close(); this.__ul.removeChild(folder.domElement.parentNode); delete this.__folders[property]; this.onResize(); } } }; if (GameLib.Utils.UndefinedOrNull(id)) { id = GameLib.Utils.RandomId(); } this.id = id; if (GameLib.Utils.UndefinedOrNull(name)) { name = 'GUI (' + id + ')'; } this.name = name; if (GameLib.Utils.UndefinedOrNull(domElement)) { console.warn('Need a DOM element for stats'); throw new Error('Need a DOM element for stats'); } this.domElement = domElement; if (GameLib.Utils.UndefinedOrNull(objects)) { objects = []; } this.objects = objects; if (GameLib.Utils.UndefinedOrNull(parentEntity)) { parentEntity = null; } this.parentEntity = parentEntity; GameLib.Component.call( this, GameLib.Component.COMPONENT_GUI, { 'domElement': GameLib.DomElement } ); }; GameLib.GUI.prototype = Object.create(GameLib.Component.prototype); GameLib.GUI.prototype.constructor = GameLib.GUI; /** * Resize function */ GameLib.GUI.prototype.resize = function() { console.log('override me per implementation'); }; /** * Creates a helper instance * @param update */ GameLib.GUI.prototype.createInstance = function(update) { var instance = null; if (update) { instance = this.instance; } else { instance = new dat.GUI( { autoPlace: false } ); } return instance; }; /** * Updates the instance with the current state */ GameLib.GUI.prototype.updateInstance = function() { this.createInstance(true); }; GameLib.GUI.prototype.addObject = function(object) { this.objects.push(object); }; GameLib.GUI.prototype.removeObject = function(object) { var index = this.objects.indexOf(object); if (index === -1) { console.warn('could not find object to remove'); return false; } else { this.objects.splice(index, 1); } return true; }; GameLib.GUI.prototype.isString = function(member) { return (typeof member === 'string'); }; GameLib.GUI.prototype.isBoolean = function(member) { return (member === true || member === false); }; GameLib.GUI.prototype.isColor = function(member) { return (member instanceof GameLib.API.Color); }; GameLib.GUI.prototype.isNumber = function(member) { return (typeof member === 'number'); }; GameLib.GUI.prototype.isVector2 = function(member) { return (member instanceof GameLib.Vector2); }; // GameLib.GUI.prototype.isColor = function(member) { // return (member instanceof GameLib.API.Color); // }; // // // Editor.prototype.isLiteral = function(object) { // return _.isString(object) || _.isBoolean(object) || _.isNumber(object) || this.isColor(object); // }; // // Editor.prototype.isEqual = function(object, object2) { // if (object instanceof GameLib.Color && object2 instanceof GameLib.Color) { // return object.r == object2.r && // object.g == object2.g && // object.b == object2.b; // } else { // return _.isEqual(object, object2); // } // }; // // Editor.prototype.isString = function(object) { // return _.isString(object); // }; // // Editor.prototype.isBoolean = function(object) { // return _.isBoolean(object); // }; // // Editor.prototype.isNumber = function(object) { // return _.isNumber(object) // }; // // Editor.prototype.isArray = function(object) { // return _.isArray(object); // }; // // Editor.prototype.isQuaternion = function(member) { // return (member instanceof GameLib.Quaternion) // }; GameLib.GUI.prototype.buildControl = function(folder, object, property, entityManager) { var handles = []; if ( this.isString(object[property]) || this.isBoolean(object[property]) ) { handles.push(folder.add(object, property).name(property).listen()); } if (this.isNumber(object[property])) { var grain = 0.001; if (object.grain) { grain = object.grain; } // if (object instanceof GameLib.Entity && property == 'componentToCreate') { // handles.push( // folder.add( // object, // property, // { // 'path_following' : GameLib.Component.COMPONENT_PATH_FOLLOWING, // 'material' : GameLib.Component.COMPONENT_MATERIAL, // 'renderer' : GameLib.Component.COMPONENT_RENDERER, // 'look_at' : GameLib.Component.COMPONENT_LOOK_AT, // 'camera' : GameLib.Component.COMPONENT_CAMERA, // 'follow' : GameLib.Component.COMPONENT_FOLLOW, // 'mesh' : GameLib.Component.COMPONENT_MESH, // 'spline' : GameLib.Component.COMPONENT_SPLINE, // 'light' : GameLib.Component.COMPONENT_LIGHT, // 'input_drive' : GameLib.Component.COMPONENT_INPUT_DRIVE, // 'composer' : GameLib.Component.COMPONENT_COMPOSER, // 'render_target' : GameLib.Component.COMPONENT_RENDER_TARGET, // 'pass' : GameLib.Component.COMPONENT_PASS, // 'scene' : GameLib.Component.COMPONENT_SCENE, // 'game' : GameLib.Component.COMPONENT_GAME, // 'input_editor' : GameLib.Component.COMPONENT_INPUT_EDITOR, // 'editor' : GameLib.Component.COMPONENT_EDITOR, // 'viewport' : GameLib.Component.COMPONENT_VIEWPORT, // 'system' : GameLib.Component.COMPONENT_SYSTEM, // 'graphics' : GameLib.Component.COMPONENT_GRAPHICS, // 'helper' : GameLib.Component.COMPONENT_HELPER, // 'custom_code' : GameLib.Component.COMPONENT_CUSTOM_CODE, // 'mouse' : GameLib.Component.COMPONENT_MOUSE, // 'skeleton' : GameLib.Component.COMPONENT_SKELETON, // 'texture' : GameLib.Component.COMPONENT_TEXTURE, // 'entity_manager' : GameLib.Component.COMPONENT_ENTITY_MANAGER // } // ).name(property).listen() // ); // // } else if (object instanceof GameLib.System && property == 'systemType') { // handles.push( // folder.add( // object, // property, // { // 'render' : GameLib.System.SYSTEM_TYPE_RENDER, // 'animation' : GameLib.System.SYSTEM_TYPE_ANIMATION, // 'input' : GameLib.System.SYSTEM_TYPE_INPUT, // 'all' : GameLib.System.SYSTEM_TYPE_ALL // } // ).name(property).listen() // ); // } else if (object instanceof GameLib.System && property === 'systemType') { handles.push( folder.add( object, property, { 'animation' : GameLib.System.SYSTEM_TYPE_ANIMATION, 'gui' : GameLib.System.SYSTEM_TYPE_GUI, 'input' : GameLib.System.SYSTEM_TYPE_INPUT, 'render' : GameLib.System.SYSTEM_TYPE_RENDER, 'storage' : GameLib.System.SYSTEM_TYPE_STORAGE } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Broadphase && property === 'broadphaseType') { handles.push( folder.add( object, property, { 'naive' : GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE, 'grid' : GameLib.D3.Image.BROADPHASE_TYPE_GRID, 'sap' : GameLib.D3.Image.BROADPHASE_TYPE_SAP } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Image && property === 'imageType') { handles.push( folder.add( object, property, { 'sphere' : GameLib.D3.Image.IMAGE_TYPE_SPHERE, 'cube' : GameLib.D3.Image.IMAGE_TYPE_CUBE, 'normal' : GameLib.D3.Image.IMAGE_TYPE_NORMAL } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Mesh && property === 'meshType') { handles.push( folder.add( object, property, { 'normal' : GameLib.D3.Mesh.MESH_TYPE_NORMAL, 'curve' : GameLib.D3.Mesh.MESH_TYPE_CURVE, 'skinned' : GameLib.D3.Mesh.MESH_TYPE_SKINNED, 'plane' : GameLib.D3.Mesh.MESH_TYPE_PLANE, 'sphere' : GameLib.D3.Mesh.MESH_TYPE_SPHERE } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'materialType') { handles.push( folder.add( object, property, { 'standard': GameLib.D3.Material.MATERIAL_TYPE_STANDARD, 'basic': GameLib.D3.Material.MATERIAL_TYPE_BASIC, 'phong': GameLib.D3.Material.MATERIAL_TYPE_PHONG, 'points': GameLib.D3.Material.MATERIAL_TYPE_POINTS } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'side') { handles.push( folder.add( object, property, { 'double': GameLib.D3.Material.TYPE_DOUBLE_SIDE, 'front': GameLib.D3.Material.TYPE_FRONT_SIDE, 'back': GameLib.D3.Material.TYPE_BACK_SIDE } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'combine') { handles.push( folder.add( object, property, { 'multiply': GameLib.D3.Material.TYPE_MULTIPLY_OPERATION, 'mix': GameLib.D3.Material.TYPE_MIX_OPERATION, 'add': GameLib.D3.Material.TYPE_ADD_OPERATION } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'vertexColors') { handles.push( folder.add( object, property, { 'none': GameLib.D3.Material.TYPE_NO_COLORS, 'face': GameLib.D3.Material.TYPE_FACE_COLORS, 'vertex': GameLib.D3.Material.TYPE_VERTEX_COLORS } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'blending') { handles.push( folder.add( object, property, { 'normal': GameLib.D3.Material.TYPE_NORMAL_BLENDING, 'additive': GameLib.D3.Material.TYPE_ADDITIVE_BLENDING, 'subtractive': GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING, 'multiply': GameLib.D3.Material.TYPE_MULTIPLY_BLENDING } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'blendSrc') { handles.push( folder.add( object, property,- { 'zero': GameLib.D3.Material.TYPE_ZERO_FACTOR, 'one': GameLib.D3.Material.TYPE_ONE_FACTOR, 'source color': GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR, 'one minus source color': GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR, 'source alpha': GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR, 'one minus source alpha': GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR, 'destination alpha': GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR, 'one minus destination alpha': GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR, 'destination color': GameLib.D3.Material.TYPE_DST_COLOR_FACTOR, 'one minus destination color': GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR, 'source alpha saturate': GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'blendDst') { handles.push( folder.add( object, property, { 'zero': GameLib.D3.Material.TYPE_ZERO_FACTOR, 'one': GameLib.D3.Material.TYPE_ONE_FACTOR, 'source color': GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR, 'one minus source color': GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR, 'source alpha': GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR, 'one minus source alpha': GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR, 'destination alpha': GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR, 'one minus destination alpha': GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR, 'destination color': GameLib.D3.Material.TYPE_DST_COLOR_FACTOR, 'one minus destination color': GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR, 'source alpha saturate': GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'blendEquation') { handles.push( folder.add( object, property, { 'add': GameLib.D3.Material.TYPE_ADD_EQUATION, 'subtract': GameLib.D3.Material.TYPE_SUBTRACT_EQUATION, 'reverse subtract': GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION, 'min': GameLib.D3.Material.TYPE_MIN_EQUATION, 'max': GameLib.D3.Material.TYPE_MAX_EQUATION } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'depthFunc') { handles.push( folder.add( object, property, { 'never': GameLib.D3.Material.TYPE_NEVER_DEPTH, 'always': GameLib.D3.Material.TYPE_ALWAYS_DEPTH, 'less depth': GameLib.D3.Material.TYPE_LESS_DEPTH, 'less equal depth': GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH, 'equal depth': GameLib.D3.Material.TYPE_EQUAL_DEPTH, 'greated equal depth': GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH, 'greated depth': GameLib.D3.Material.TYPE_GREATER_DEPTH, 'not equal depth': GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Material && property === 'shading') { handles.push( folder.add( object, property, { 'flat': GameLib.D3.Material.TYPE_FLAT_SHADING, 'smooth': GameLib.D3.Material.TYPE_SMOOTH_SHADING } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'wrapS') { handles.push( folder.add( object, property, { 'repeat': GameLib.D3.Texture.TYPE_REPEAT_WRAPPING, 'clamp': GameLib.D3.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING, 'mirrored repeat': GameLib.D3.Texture.TYPE_MIRRORED_REPEAT_WRAPPING } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'wrapT') { handles.push( folder.add( object, property, { 'repeat': GameLib.D3.Texture.TYPE_REPEAT_WRAPPING, 'clamp': GameLib.D3.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING, 'mirrored repeat': GameLib.D3.Texture.TYPE_MIRRORED_REPEAT_WRAPPING } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'format') { handles.push( folder.add( object, property, { 'alpha': GameLib.D3.Texture.TYPE_ALPHA_FORMAT, 'rgb': GameLib.D3.Texture.TYPE_RGB_FORMAT, 'rgba': GameLib.D3.Texture.TYPE_RGBA_FORMAT, 'luminance': GameLib.D3.Texture.TYPE_LUMINANCE_FORMAT, 'luminance alpha': GameLib.D3.Texture.TYPE_LUMINANCE_ALPHA_FORMAT, 'depth': GameLib.D3.Texture.TYPE_DEPTH_FORMAT } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'mapping') { handles.push( folder.add( object, property, { 'uv': GameLib.D3.Texture.TYPE_UV_MAPPING, 'cube reflection': GameLib.D3.Texture.TYPE_CUBE_REFLECTION_MAPPING, 'cube refraction': GameLib.D3.Texture.TYPE_CUBE_REFRACTION_MAPPING, 'equi rectangular reflection': GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING, 'equi rectangular refraction': GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING, 'spherical reflection': GameLib.D3.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING, 'cube uv reflection': GameLib.D3.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING, 'cube uv refraction': GameLib.D3.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'magFilter') { handles.push( folder.add( object, property, { 'nearest': GameLib.D3.Texture.TYPE_NEAREST_FILTER, 'nearest mipmap nearest': GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER, 'nearest mipmap linear': GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER, 'linear': GameLib.D3.Texture.TYPE_LINEAR_FILTER, 'linear mipmap nearest': GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER, 'linear mipmap linear': GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'minFilter') { handles.push(folder.add( object, property, { 'nearest': GameLib.D3.Texture.TYPE_NEAREST_FILTER, 'nearest mipmap nearest': GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER, 'nearest mipmap linear': GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER, 'linear': GameLib.D3.Texture.TYPE_LINEAR_FILTER, 'linear mipmap nearest': GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER, 'linear mipmap linear': GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'typeId') { handles.push( folder.add( object, property, { 'normal': GameLib.D3.Texture.TEXTURE_TYPE_NORMAL, 'cube': GameLib.D3.Texture.TEXTURE_TYPE_CUBE } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'textureType') { handles.push( folder.add( object, property, { 'unsigned byte': GameLib.D3.Texture.TYPE_UNSIGNED_BYTE, 'byte': GameLib.D3.Texture.TYPE_BYTE, 'short': GameLib.D3.Texture.TYPE_SHORT, 'unsigned short': GameLib.D3.Texture.TYPE_UNSIGNED_SHORT, 'int': GameLib.D3.Texture.TYPE_INT, 'unsigned int': GameLib.D3.Texture.TYPE_UNSIGNED_INT, 'float': GameLib.D3.Texture.TYPE_FLOAT, 'half float': GameLib.D3.Texture.TYPE_HALF_FLOAT } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Texture && property === 'encoding') { handles.push( folder.add( object, property, { 'linear': GameLib.D3.Texture.TYPE_LINEAR_ENCODING, 'srgb': GameLib.D3.Texture.TYPE_SRGB_ENCODING, 'gamma': GameLib.D3.Texture.TYPE_GAMMA_ENCODING, 'rgbe': GameLib.D3.Texture.TYPE_RGBE_ENCODING, 'log luv': GameLib.D3.Texture.TYPE_LOG_LUV_ENCODING, 'rgbm7': GameLib.D3.Texture.TYPE_RGBM7_ENCODING, 'rgbm16': GameLib.D3.Texture.TYPE_RGBM16_ENCODING, 'rgbd': GameLib.D3.Texture.TYPE_RGBD_ENCODING } ).name(property).listen() ); } else if (object instanceof GameLib.D3.Light && property === 'lightType') { handles.push( folder.add( object, property, { 'ambient': GameLib.D3.Light.LIGHT_TYPE_AMBIENT, 'directional': GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL, 'spot': GameLib.D3.Light.LIGHT_TYPE_SPOT, 'point': GameLib.D3.Light.LIGHT_TYPE_POINT } ).name(property).listen() ); } else { /** * Try to guess a scale for this property */ if ( property === 'opacity' || property === 'metalness' || property === 'roughness' ) { handles.push(folder.add(object, property, 0, 1.0).step(0.001).name(property).listen()); } else if ( property === 'shininess' || property === 'fov' ) { handles.push(folder.add(object, property, -255, 255).step(1).name(property).listen()); } else if ( property === 'aspect' ) { handles.push(folder.add(object, property, 0, 5).step(0.001).name(property).listen()); } else if ( property === 'widthSegments' || property === 'heightSegments' ) { handles.push(folder.add(object, property, 1, 1000).step(1).name(property).listen()); } else if ( property === 'angle' || property === 'width' || property === 'height' || property === 'depth' ) { handles.push(folder.add(object, property, -1000, 1000).step(1).name(property).listen()); } else if ( property === 'near' || property === 'distanceGrain' || property === 'bumpScale' || property === 'envMapIntensity' ) { handles.push(folder.add(object, property, -10, 100).step(0.001).name(property).listen()); } else if ( property === 'heightOffset' || property === 'rotationFactor' ) { handles.push(folder.add(object, property, -100, 100).step(0.001).name(property).listen()); } else { handles.push(folder.add(object, property, -10000, 10000).step(grain).name(property).listen()); } } } if (this.isColor(object[property])) { handles.push(folder.addColor({hexColor : object[property].toHex()}, 'hexColor').name(property).listen()); } // // if (this.isFutureObject(object, property)) { // // var result = this.getObjectPropertyType(object, property); // // var objectType = result.propertyType; // // var isArray = result.isArray; // // if (isArray) { // // // // } else { // // var selection = {}; // // selection['select...'] = null; // // var guiObject = { // id : null // }; // // for (var o in idToObject) { // if (idToObject.hasOwnProperty(o)) { // if (idToObject[o] instanceof objectType) { // // var name = idToObject[o].name; // // if (name.indexOf(idToObject[o].id) == -1) { // name += '(' + idToObject[o].id + ')'; // } // // selection[name] = idToObject[o].id; // // if (object[property] && object[property].id == idToObject[o].id) { // guiObject.id = idToObject[o].id; // } // } // } // } // // handles.push( // folder.add( // guiObject, // 'id', // selection // ).name(property).listen() // ); // } // // var createObjectFunction = function(constructor, __object, __property, editor) { // return function() { // // if (__object[__property] instanceof Array) { // __object[__property].push(new constructor( // editor.graphics // )); // } else { // __object[__property] = new constructor( // editor.graphics // ); // } // // editor.editor.buildIdToObject(); // // editor.buildObjectSelection(); // // editor.buildGUI(); // } // }(objectType, object, property, this); // // var createObject = { // 'create': createObjectFunction // }; // // folder.add( // createObject, // 'create' // ).name('create a ' + property.replace(/s$/,'')); // } // // handles.map(function(handle){ // // handle.onChange( // this.onPropertyChange( // this, // affectedObjectProperties // ) // ); // // // }); handles.map( function(gui) { return function(handle) { if (property === 'name') { handle.onFinishChange( function(){gui.build(entityManager)} ); } else { handle.onChange( function (value) { if (object[property] instanceof GameLib.Color) { object[property].fromHex(value); object[property].updateInstance(); } else if (typeof this.initialValue === 'number') { object[property] = Number(value); } else { object[property] = value; } if (object instanceof GameLib.D3.Texture && property === 'typeId') { var imageFactory = entityManager.queryComponents(GameLib.D3.ImageFactory)[0]; if (object.image) { object.publish( GameLib.Event.LOAD_IMAGE, { id : object.image.id, textureType : object[property], baseUrl : imageFactory.baseUrl } ) } else { console.log('changing texture type but no image specified') } } object.updateInstance(); // object.needsUpdate = true; } ); } } }(this) ); }; GameLib.GUI.prototype.buildVectorControl = function(folder, object, property, dimension) { var step = 0.1; if (property === 'localRotation') { step = 0.001; } if (dimension === 4) { folder.add( object[property], 'w', -100, 100 ).name(property + '.w').listen().step(step).onChange( function() { object.updateInstance(); } ); } folder.add( object[property], 'x', -100, 100 ).name(property + '.x').listen().step(step).onChange( function() { object.updateInstance(); } ); folder.add( object[property], 'y', -100, 100 ).name(property + '.y').listen().step(step).onChange( function() { object.updateInstance(); } ); if ( dimension === 3 || dimension === 4 ) { folder.add( object[property], 'z', -100, 100 ).name(property + '.z').listen().step(step).onChange( function() { object.updateInstance(); } ); } }; GameLib.GUI.prototype.buildSelectControl = function(folder, object, property, entityManager, constructor, parentObject) { var objects = entityManager.queryComponents(constructor); var idToObject = {}; var options = objects.reduce( function(result, obj) { result[obj.name] = obj; idToObject[obj.id] = obj; return result; }, { 'none' : null } ); folder.add( object, property, options ).name(property).listen().onChange( function(gui) { return function (value) { if (value !== 'null') { object[property] = idToObject[value]; } else { object[property] = null; } if (property === 'parentScene') { /** * New way of doing things */ GameLib.Event.Emit( GameLib.Event.PARENT_SCENE_CHANGE, { originalScene: this.initialValue, newScene: object[property], object: object, entityManager: entityManager } ); } else if (property === 'image') { GameLib.Event.Emit( GameLib.Event.IMAGE_CHANGE, { originalImage: this.initialValue, newImage: object[property], object: object, entityManager: entityManager } ); } else { /** * Old way of doing things */ object.updateInstance(); } /** * Properties changed - rebuild the object list in the parent */ console.log('parentObject.buildIdToObject();'); /** * Properties changed - rebuild GUI */ gui.build(entityManager); }; }(this) ); }; /** * */ GameLib.GUI.prototype.buildArrayManager = function( folder, object, property, constructor, entityManager ) { var array = object[property]; var addArrayItem = function(item, index){ var controller = folder.add( { 'remove' : function() { object[property].splice(object[property].indexOf(item), 1); folder.remove(controller); } }, 'remove' ).name('remove ' + property + '[' + index + '] - ' + item.name); }; array.map(addArrayItem); var idToObject = {}; var selectionObject = entityManager.queryComponents(constructor).reduce( function(result, component) { result[component.name] = component; idToObject[component.id] = component; return result; }, { 'none' : null } ); var activeSelection = function(__object, __property) { var object = __object; var property = __property; return { component : null, add : function() { if (object[property].indexOf(activeSelection.component) === -1) { object[property].push(activeSelection.component); addArrayItem(activeSelection.component, object[property].length - 1) } } }; }(object, property); folder.add(activeSelection, 'component', selectionObject).name('select ' + property).onChange( function(value){ if (value === 'null') { activeSelection['component'] = null; } else { activeSelection['component'] = idToObject[value]; } } ).listen(); folder.add(activeSelection, 'add').name('add to ' + property); }; GameLib.GUI.prototype.buildEntitySelectionControlFromArray = function( folder, object, property, entityManager ) { var options = entityManager.entities.reduce( function(result, obj){ if (obj instanceof Object) { result[obj.name] = obj; } else { console.log('not an object'); } return result; }, { 'none' : null } ); folder.add(object, property, options).name(property).listen().onChange( function(entityManager, gui) { return function(value) { if (value !== 'null') { object[property] = entityManager.findEntityById(value); } else { object[property] = null; } GameLib.Event.Emit( GameLib.Event.PARENT_ENTITY_CHANGE, { originalEntity : this.initialValue, newEntity : entityManager.findEntityById(value), object : object } ); this.initialValue = entityManager.findEntityById(value); }; }(entityManager, this) ).onFinishChange(function(gui, entityManager){ return function() { gui.build(entityManager); } }(this, entityManager)); }; /** * Builds the GUI */ GameLib.GUI.prototype.build = function(entityManager) { this.instance.removeAllFolders(); var discoveredObjects = []; var parentObject = this.objects[0]; this.objects.map( function(object) { if (object.idToObject) { for (var property in object.idToObject) { if (object.idToObject.hasOwnProperty(property)) { if (discoveredObjects.indexOf(object.idToObject[property]) === -1) { discoveredObjects.push(object.idToObject[property]); } } } } }.bind(this) ); discoveredObjects.sort( function(a, b) { if (a.name > b.name) { return 1; } if (a.name < b.name) { return -1; } return 0; } ); discoveredObjects.map( function(object) { var apiObject = object.toApiObject(); if (typeof(apiObject) === 'string') { return; } var folder = null; try { folder = this.instance.addFolder(apiObject.name); } catch (e) { console.log(e.message); return; } if (!folder) { throw new Error('Could not create folder'); } var property; for (property in apiObject) { if ( apiObject.hasOwnProperty(property) && object.hasOwnProperty(property) ) { if ( object.linkedObjects && object.linkedObjects[property] ) { if (property === 'parentEntity') { this.buildEntitySelectionControlFromArray( folder, object, property, entityManager ) } else if (object.linkedObjects[property] instanceof Array) { console.log('ignored array : ' + property); this.buildArrayManager( folder, object, property, object.linkedObjects[property], entityManager ) } else { this.buildSelectControl(folder, object, property, entityManager, object.linkedObjects[property], parentObject); } } else if (typeof (object[property]) === 'object') { if (this.isColor(object[property])) { this.buildControl(folder, object, property); } else if (object[property] instanceof GameLib.Vector2) { this.buildVectorControl(folder, object, property, 2); } else if (object[property] instanceof GameLib.Vector3) { this.buildVectorControl(folder, object, property, 3); } else if (object[property] instanceof GameLib.Vector4) { this.buildVectorControl(folder, object, property, 4); } else { console.log('ignored: ' + property); } } else { this.buildControl(folder, object, property, entityManager); } } } for (property in object) { if (typeof (object[property]) === 'function') { folder.add(object, property); } } }.bind(this) ); };