r3-legacy/src/game-lib-system-gui.js

1304 lines
33 KiB
JavaScript
Raw Normal View History

2017-06-19 15:54:02 +02:00
/**
* System takes care of updating all the entities (based on their component data)
* @param apiSystem GameLib.API.System
* @constructor
*/
GameLib.System.GUI = function(
apiSystem
) {
GameLib.System.call(
this,
apiSystem
);
2017-06-29 15:23:50 +02:00
this.guis = [];
2017-08-23 17:53:06 +02:00
this.components = [];
/**
* When we want to show a specific set of components - we backup the current components and then restore them
* later when we are done.
* @type {null}
*/
this.backupComponents = null;
this.exclusiveMode = false;
2017-06-29 15:23:50 +02:00
this.buildGUISubscription = null;
this.meshDeletedSubscription = null;
this.meshSelectedSubscription = null;
this.meshDeselectedSubscription = null;
this.newEntitySubscription = null;
this.meshSelectionObjects = {};
2017-06-19 15:54:02 +02:00
};
GameLib.System.GUI.prototype = Object.create(GameLib.System.prototype);
GameLib.System.GUI.prototype.constructor = GameLib.System.GUI;
GameLib.System.GUI.prototype.start = function() {
2017-06-29 15:23:50 +02:00
this.guis = GameLib.EntityManager.Instance.queryComponents(GameLib.GUI);
2017-06-19 15:54:02 +02:00
/**
* Add some GUI behaviour
*/
dat.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();
}
}
}
};
dat.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();
}
}
};
2017-06-29 15:23:50 +02:00
this.guis.map(function(gui){
2017-06-19 15:54:02 +02:00
gui.domElement.instance.parentElement.appendChild(gui.instance.domElement);
2017-06-29 15:23:50 +02:00
});
this.buildGUISubscription = this.subscribe(
GameLib.Event.BUILD_GUI,
this.buildGUI
);
this.meshDeletedSubscription = this.subscribe(
GameLib.Event.MESH_DELETED,
this.meshDeleted
);
this.meshSelectedSubscription = this.subscribe(
GameLib.Event.MESH_SELECTED,
2017-08-23 17:53:06 +02:00
this.meshSelected
2017-06-29 15:23:50 +02:00
);
this.meshDeselectedSubscription = this.subscribe(
GameLib.Event.MESH_DESELECTED,
2017-08-23 17:53:06 +02:00
this.meshDeslected
2017-06-29 15:23:50 +02:00
);
this.newEntitySubscription = this.subscribe(
GameLib.Event.NEW_ENTITY,
this.newEntity
2017-08-23 17:53:06 +02:00
);
this.componentRemovedSubscription = this.subscribe(
GameLib.Event.COMPONENT_REMOVE,
this.removeComponent
)
};
GameLib.System.GUI.prototype.buildVectorControl = function(folder, templateObject, property, dimension) {
var step = 0.1;
var object = templateObject.template;
var affected = templateObject.affected;
if (
property === 'localRotation' ||
property === 'localPosition'
) {
step = 0.001;
}
if (dimension === 4) {
folder.add(
object[property],
'w',
-100,
100,
step
).name(property + '.w').listen().onChange(
function(value) {
affected.map(function(component){
component[property].w = value;
component.updateInstance();
}.bind(this));
}
);
}
folder.add(
object[property],
'x',
-100,
100,
step
).name(property + '.x').listen().onChange(
function(value) {
affected.map(function(component){
component[property].x = value;
component.updateInstance();
}.bind(this));
}
);
folder.add(
object[property],
'y',
-100,
100,
step
).name(property + '.y').listen().onChange(
function(value) {
affected.map(function(component){
component[property].y = value;
component.updateInstance();
}.bind(this));
}
);
if (
dimension === 3 ||
dimension === 4
) {
folder.add(
object[property],
'z',
-100,
100,
step
).name(property + '.z').listen().onChange(
function(value) {
affected.map(function(component){
component[property].z = value;
component.updateInstance();
}.bind(this));
}
);
}
};
/**
* Builds an Entity Selection control
* @param folder
* @param componentTemplate
*/
GameLib.System.GUI.prototype.buildEntitySelectionControl = function(folder, componentTemplate) {
var options = GameLib.EntityManager.Instance.queryComponents(GameLib.Entity).reduce(
function(result, entity) {
result[entity.name] = entity;
return result;
},
{
'none' : null
}
);
var object = componentTemplate.template;
var affected = componentTemplate.affected;
folder.add(object, 'parentEntity', options).listen().onChange(
function(value) {
var newEntity = null;
if (value !== 'null') {
newEntity = GameLib.EntityManager.Instance.findEntityById(value);
}
affected.map(
function(component) {
component.parentEntity = newEntity;
GameLib.Event.Emit(
GameLib.Event.PARENT_ENTITY_CHANGE,
{
originalEntity : this.initialValue,
newEntity : newEntity,
object : component
}
);
}.bind(this)
);
this.initialValue = newEntity;
}
).onFinishChange(
function(){
// GameLib.Event.Emit(
// GameLib.Event.BUILD_GUI,
// {
//
// }
// )
}
);
};
GameLib.System.GUI.prototype.buildArrayManagerControl = function(
folder,
componentTemplate,
property,
constructor
) {
console.log('TODO: array manager control');
// 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.System.GUI.prototype.buildSelectControl = function(folder, object, property, entityManager, constructor) {
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 {
/**
* Old way of doing things
*/
object.updateInstance();
}
/**
* Properties changed - rebuild GUI
*/
//gui.build(entityManager);
};
}(this)
);
};
GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, property) {
var object = componentTemplate.template;
var componentType = componentTemplate.componentType;
var handles = [];
if (
GameLib.Utils.isString(object[property]) ||
GameLib.Utils.isBoolean(object[property])
) {
handles.push(folder.add(object, property).name(property).listen());
}
if (GameLib.Utils.isNumber(object[property])) {
var grain = 0.001;
if (object.grain) {
grain = object.grain;
}
if (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,
'linking' : GameLib.System.SYSTEM_TYPE_LINKING,
'physics' : GameLib.System.SYSTEM_TYPE_PHYSICS
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (componentType === GameLib.Component.COMPONENT_TEXTURE && property === 'typeId') {
handles.push(
folder.add(
object,
property,
{
'normal': GameLib.D3.Texture.TEXTURE_TYPE_NORMAL,
'cube': GameLib.D3.Texture.TEXTURE_TYPE_CUBE
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).listen()
);
} else if (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
}
).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, 0.001).listen());
} else if (
property === 'shininess' ||
property === 'fov'
) {
handles.push(folder.add(object, property, -255, 255, 1).listen());
} else if (
property === 'aspect'
) {
handles.push(folder.add(object, property, 0, 5, 0.001).listen());
} else if (
property === 'widthSegments' ||
property === 'heightSegments'
) {
handles.push(folder.add(object, property, 1, 1000, 1).listen());
} else if (
property === 'angle' ||
property === 'width' ||
property === 'height' ||
property === 'depth'
) {
handles.push(folder.add(object, property, -1000, 1000, 1).listen());
} else if (
property === 'near' ||
property === 'distanceGrain' ||
property === 'bumpScale' ||
property === 'envMapIntensity'
) {
handles.push(folder.add(object, property, -10, 100, 0.001).listen());
} else if (
property === 'heightOffset' ||
property === 'rotationFactor'
) {
handles.push(folder.add(object, property, -100, 100, 0.001).step(0.001).listen());
} else {
handles.push(folder.add(object, property, -10000, 10000, grain).listen());
}
}
}
handles.map(
function(handle) {
if (property === 'name') {
handle.onFinishChange(
function(__handle) {
return function(value) {
componentTemplate.affected.map(
function(component){
component[property] = value;
component.updateInstance();
}
);
}
}(handle)
);
} else {
handle.onChange(
function (value) {
if (typeof this.initialValue === 'number') {
value = Number(value);
}
componentTemplate.affected.map(
function(component){
component[property] = value;
component.updateInstance();
}
);
}
);
}
}
);
};
/**
* Push the mesh to our backup components, if in exclusiveMode (menu at top is selected),
* otherwise, just to our normal components
* @param data
*/
GameLib.System.GUI.prototype.meshSelected = function(data) {
if (this.exclusiveMode) {
GameLib.Utils.PushUnique(this.backupComponents, data.mesh);
} else {
GameLib.Utils.PushUnique(this.components, data.mesh);
}
};
/**
* Same as selected above, but removes the mesh from the components
* @param data
*/
GameLib.System.GUI.prototype.meshDeslected = function(data) {
var index = -1;
if (this.exclusiveMode) {
index = this.backupComponents.indexOf(data.mesh);
if (index !== -1) {
this.backupComponents.splice(index, 1);
}
} else {
index = this.components.indexOf(data.mesh);
if (index !== -1) {
this.components.splice(index, 1);
}
}
2017-06-19 15:54:02 +02:00
};
2017-08-23 17:53:06 +02:00
/**
* This function responds to the BUILD_GUI event, data contains the components to build a GUI for
* @param data
*/
2017-06-29 15:23:50 +02:00
GameLib.System.GUI.prototype.buildGUI = function(data) {
2017-06-19 15:54:02 +02:00
2017-06-29 15:23:50 +02:00
this.guis.map(function(gui){
/**
2017-08-23 17:53:06 +02:00
* First, start fresh - remove all folders
*/
2017-08-23 17:53:06 +02:00
gui.removeAllFolders();
if (data) {
if (data.components) {
this.exclusiveMode = true;
/**
* Backup the current selection
*/
this.backupComponents = this.components.map(
function(component) {
return component;
}
);
this.components = data.components.map(
function(component) {
return component;
}
);
} else {
2017-06-29 15:23:50 +02:00
2017-08-23 17:53:06 +02:00
this.exclusiveMode = false;
/**
* Time to restore the backup
*/
this.components = this.backupComponents.map(
function(component) {
return component;
}
)
}
}
2017-06-29 15:23:50 +02:00
/**
2017-08-23 17:53:06 +02:00
* For all mesh components - (if not in exclusive mode) - try to discover all materials, textures, etc
*/
2017-08-23 17:53:06 +02:00
if (!this.exclusiveMode) {
/**
* We first remove everything which is not a Mesh
*/
this.components = this.components.filter(
function (component) {
return (component instanceof GameLib.D3.Mesh);
}
);
}
/**
* Check if we have components to build a GUI for
*/
if (GameLib.Utils.UndefinedOrNull(this.components.length) || this.components.length < 1) {
console.log('no components selected');
return;
}
/**
* Now continue to discover materials, textures, images etc. children of this component
*/
if (!this.exclusiveMode) {
this.components = this.components.reduce(
function(result, component) {
var components = component.getChildrenComponents();
GameLib.Utils.PushUnique(result, component);
components.map(function(component){
GameLib.Utils.PushUnique(result, component);
});
return result;
}.bind(this),
[]
);
}
/**
* Sort the components by component type
*/
2017-08-23 17:53:06 +02:00
this.components.sort(
function(a, b) {
if (a.componentType > b.componentType) {
return 1;
}
if (a.componentType < b.componentType) {
return -1;
}
return 0;
}
);
/**
* Split the components into groups of componentType
*/
2017-08-23 17:53:06 +02:00
var componentGroups = this.components.reduce(
function(result, component) {
var componentData = result.pop();
if (component.componentType === componentData.componentType) {
/**
* This is the first component
*/
componentData.components.push(component);
result.push(componentData);
return result;
}
2017-06-29 15:23:50 +02:00
if (component.componentType !== componentData.componentType) {
result.push(componentData);
result.push({
componentType : component.componentType,
components:[component]
});
return result;
}
2017-06-29 15:23:50 +02:00
},
[
{
2017-08-23 17:53:06 +02:00
componentType : this.components[0].componentType,
components : []
}
]
);
2017-06-29 15:23:50 +02:00
2017-08-23 17:53:06 +02:00
/**
* We have all the components split into groups - now add the individual components
*/
this.components.map(
function(component) {
/**
* Check for possible duplicates
* @type {boolean}
*/
var duplicate = false;
componentGroups.map(function(componentGroup){
if (
componentGroup.componentType === component.componentType &&
componentGroup.components.length === 1 &&
componentGroup.components[0] === component
) {
duplicate = true;
}
});
if (!duplicate) {
GameLib.Utils.PushUnique(
componentGroups,
{
componentType : component.componentType,
components : [component]
}
);
}
}
);
/**
* componentGroups should now contain the whole list of stuff we want to build GUI for.
*/
componentGroups.map(
2017-06-29 15:23:50 +02:00
function(componentGroup){
if (componentGroup.components.length < 1) {
console.warn('invalid number of components');
}
var templateObject = {
template : {
/**
* Doing this here is just to put parentEntity at the top of the gui
*/
'parentEntity' : componentGroup.components[0].parentEntity
},
affected : [componentGroup.components[0]],
componentType : componentGroup.componentType
};
for (var property in componentGroup.components[0]) {
if (
componentGroup.components[0].hasOwnProperty(property) ||
typeof componentGroup.components[0][property] === 'function'
) {
if (typeof componentGroup.components[0][property] === 'function') {
templateObject.template[property] = function(__property) {
return function() {
this.affected.map(
function(component) {
component[__property].bind(component)();
}
)
}.bind(templateObject);
}(property);
} else {
templateObject.template[property] = componentGroup.components[0][property];
}
}
}
var componentTemplate = componentGroup.components.reduce(
function(result, component) {
if (component === componentGroup.components[0]) {
/**
* This is the first component, just return
*/
return result;
}
/**
* Now start to filter out the properties
*/
for (var property in component) {
if (
component.hasOwnProperty(property)
) {
if (!result.template.hasOwnProperty(property)) {
continue;
}
if (
result.template[property] instanceof GameLib.Vector2 ||
result.template[property] instanceof GameLib.Vector3 ||
result.template[property] instanceof GameLib.Vector4
) {
if (!result.template[property].equals(component[property])) {
delete result.template[property];
}
continue;
}
if (result.template[property] !== component[property]) {
delete result.template[property];
}
}
}
/**
* Store the affected component
*/
result.affected.push(component);
return result;
},
templateObject
);
/**
* componentTemplate now contains for this particular component type group - all
* the properties which are modifiable, and also the objects affected by this property changes
*/
var name;
if (GameLib.Utils.UndefinedOrNull(componentTemplate.template.name)) {
2017-08-23 17:53:06 +02:00
name = GameLib.Component.GetComponentName(componentTemplate.componentType) + ' (All Selected (' + componentTemplate.affected.length + '))';
} else {
name = componentTemplate.template.name;
}
var folder = gui.addFolder(name);
if (!folder) {
2017-08-23 17:53:06 +02:00
return;
}
for (var templateProperty in componentTemplate.template) {
if (
componentTemplate.template.hasOwnProperty(templateProperty) ||
typeof (componentTemplate.template[templateProperty]) === 'function'
) {
if (typeof (componentTemplate.template[templateProperty]) === 'function') {
folder.add(componentTemplate.template, templateProperty);
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector2) {
2017-08-23 17:53:06 +02:00
this.buildVectorControl(folder, componentTemplate, templateProperty, 2);
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector3) {
2017-08-23 17:53:06 +02:00
this.buildVectorControl(folder, componentTemplate, templateProperty, 3);
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector4) {
2017-08-23 17:53:06 +02:00
this.buildVectorControl(folder, componentTemplate, templateProperty, 4);
continue;
}
if (templateProperty === 'parentEntity') {
this.buildEntitySelectionControl(folder, componentTemplate);
continue;
}
2017-08-23 17:53:06 +02:00
if (componentTemplate.template[templateProperty] instanceof Array) {
this.buildArrayManagerControl(folder, componentTemplate, templateProperty);
continue;
}
if (typeof componentTemplate.template[templateProperty] === 'object') {
/**
* ignore objects for now
*/
continue;
}
this.buildControl(folder, componentTemplate, templateProperty);
// if (
// component.linkedObjects &&
// component.linkedObjects[property]
// ) {
// if (property === 'parentEntity') {
// this.buildEntitySelectionControlFromArray(
// folder,
// component,
// property,
// entityManager
// )
// } else if (component.linkedObjects[property] instanceof Array) {
// this.buildArrayManager(
// folder,
// component,
// property,
// component.linkedObjects[property],
// entityManager
// )
// } else {
// this.buildSelectControl(folder, component, property, entityManager, component.linkedObjects[property]);
// }
//
// } else if (typeof (component[property]) === 'object') {
//
// if (this.isColor(component[property])) {
// this.buildControl(folder, component, property);
// } else {
// //console.log('ignored: ' + property);
// }
// } else {
// this.buildControl(folder, component, property, entityManager);
// }
}
}
2017-08-23 17:53:06 +02:00
}.bind(this)
);
2017-08-23 17:53:06 +02:00
}.bind(this));
2017-06-29 15:23:50 +02:00
};
GameLib.System.GUI.prototype.meshDeleted = function(data) {
2017-06-29 15:23:50 +02:00
2017-08-23 17:53:06 +02:00
data.meshes.map(function(mesh){
this.meshDeslected({
mesh : mesh
})
}.bind(this));
2017-08-23 17:53:06 +02:00
this.buildGUI(null);
};
2017-08-23 17:53:06 +02:00
GameLib.System.GUI.prototype.removeComponent = function(data) {
2017-08-23 17:53:06 +02:00
var index = this.backupComponents.indexOf(data.component);
if (index !== -1) {
this.backupComponents.splice(index, 1);
}
2017-08-23 17:53:06 +02:00
index = this.components.indexOf(data.component);
if (index !== -1) {
this.components.splice(index, 1);
}
};
2017-06-29 15:23:50 +02:00
GameLib.System.GUI.prototype.newEntity = function(data) {
};
GameLib.System.GUI.prototype.stop = function() {
this.guis.map(function(gui){
2017-06-19 15:54:02 +02:00
gui.domElement.instance.parentElement.removeChild(gui.instance.domElement);
2017-06-29 15:23:50 +02:00
});
delete dat.GUI.removeEmtpyFolders;
delete dat.GUI.removeAllFolders;
2017-06-29 15:23:50 +02:00
this.buildGUISubscription.remove();
this.meshDeletedSubscription.remove();
this.meshSelectedSubscription.remove();
this.meshDeselectedSubscription.remove();
this.newEntitySubscription.remove();
2017-08-23 17:53:06 +02:00
this.componentRemovedSubscription.remove();
2017-06-29 15:23:50 +02:00
this.guis = [];
2017-06-19 15:54:02 +02:00
};