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}
|
|
|
|
*/
|
2017-08-24 22:20:40 +02:00
|
|
|
this.backupComponents = [];
|
2017-08-23 17:53:06 +02:00
|
|
|
|
|
|
|
this.exclusiveMode = false;
|
2017-08-22 19:18:14 +02:00
|
|
|
|
2017-06-29 15:23:50 +02:00
|
|
|
this.buildGUISubscription = null;
|
|
|
|
|
|
|
|
this.meshDeletedSubscription = null;
|
|
|
|
|
|
|
|
this.meshSelectedSubscription = null;
|
|
|
|
|
|
|
|
this.meshDeselectedSubscription = null;
|
|
|
|
|
|
|
|
this.newEntitySubscription = null;
|
|
|
|
|
2017-06-30 12:06:55 +02:00
|
|
|
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
|
|
|
|
2017-08-22 19:18:14 +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);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
GameLib.System.GUI.prototype.buildColorControl = function(folder, componentTemplate, property) {
|
2017-08-23 17:53:06 +02:00
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
var object = componentTemplate.template;
|
|
|
|
|
|
|
|
folder.addColor(
|
|
|
|
{
|
|
|
|
hexColor : object[property].toHex()
|
|
|
|
},
|
|
|
|
'hexColor'
|
|
|
|
).name(property).listen().onChange(
|
|
|
|
function(value) {
|
|
|
|
componentTemplate.affected.map(
|
|
|
|
function(component) {
|
|
|
|
component[property].fromHex(value);
|
|
|
|
component[property].updateInstance();
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.System.GUI.prototype.buildSelectControl = function(folder, componentTemplate, property) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* We need to discover the constructor for this component
|
|
|
|
*/
|
|
|
|
var constructor = componentTemplate.template[property].constructor;
|
|
|
|
|
|
|
|
var object = componentTemplate.template;
|
|
|
|
|
|
|
|
var objects = GameLib.EntityManager.Instance.queryComponents(constructor);
|
2017-08-23 17:53:06 +02:00
|
|
|
|
|
|
|
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(
|
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
function (value) {
|
2017-08-23 17:53:06 +02:00
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
var newComponent = null;
|
2017-08-23 17:53:06 +02:00
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
var originalComponent = this.initialValue;
|
2017-08-23 17:53:06 +02:00
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
if (value !== 'null') {
|
|
|
|
newComponent = idToObject[value];
|
|
|
|
}
|
2017-08-23 17:53:06 +02:00
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
componentTemplate.affected.map(
|
|
|
|
function(component) {
|
|
|
|
component[property] = newComponent;
|
|
|
|
component.updateInstance();
|
2017-08-23 17:53:06 +02:00
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
if (property === 'parentScene') {
|
|
|
|
GameLib.Event.Emit(
|
|
|
|
GameLib.Event.PARENT_SCENE_CHANGE,
|
|
|
|
{
|
|
|
|
originalScene: originalComponent,
|
|
|
|
newScene: newComponent,
|
|
|
|
object: component
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2017-08-23 17:53:06 +02:00
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
this.initialValue = newComponent;
|
|
|
|
}
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, property) {
|
|
|
|
|
|
|
|
var object = componentTemplate.template;
|
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
var listen = false;
|
|
|
|
|
|
|
|
if (componentTemplate.affected.length === 1) {
|
|
|
|
/**
|
|
|
|
* If the template only affects a single object - put the handle on this so we can listen for changes
|
|
|
|
*/
|
|
|
|
//object = componentTemplate.affected[0];
|
|
|
|
|
|
|
|
listen = true;
|
|
|
|
}
|
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
var componentType = componentTemplate.componentType;
|
|
|
|
|
|
|
|
var handles = [];
|
|
|
|
|
|
|
|
if (
|
|
|
|
GameLib.Utils.isString(object[property]) ||
|
|
|
|
GameLib.Utils.isBoolean(object[property])
|
|
|
|
) {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property));
|
2017-08-23 17:53:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} else if (property === 'blendSrc') {
|
|
|
|
handles.push(
|
|
|
|
folder.add(
|
|
|
|
object,
|
2017-08-24 22:20:40 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} else if (property === 'minFilter') {
|
2017-08-24 22:20:40 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} 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
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
)
|
|
|
|
);
|
|
|
|
} else if (property === 'eventId') {
|
|
|
|
|
|
|
|
var options = {};
|
|
|
|
|
|
|
|
for (var i = 0; i < 200; i++) {
|
|
|
|
try {
|
|
|
|
options[GameLib.Event.GetEventName(i)] = i;
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handles.push(
|
|
|
|
folder.add(
|
|
|
|
object,
|
|
|
|
property,
|
|
|
|
options
|
|
|
|
)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Try to guess a scale for this property
|
|
|
|
*/
|
|
|
|
if (
|
|
|
|
property === 'opacity' ||
|
|
|
|
property === 'metalness' ||
|
|
|
|
property === 'roughness'
|
|
|
|
) {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property, 0, 1.0, 0.001));
|
2017-08-23 17:53:06 +02:00
|
|
|
} else if (
|
|
|
|
property === 'shininess' ||
|
|
|
|
property === 'fov'
|
|
|
|
) {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property, -255, 255, 1));
|
2017-08-23 17:53:06 +02:00
|
|
|
} else if (
|
|
|
|
property === 'aspect'
|
|
|
|
) {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property, 0, 5, 0.001));
|
2017-08-23 17:53:06 +02:00
|
|
|
} else if (
|
|
|
|
property === 'widthSegments' ||
|
|
|
|
property === 'heightSegments'
|
|
|
|
) {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property, 1, 1000, 1));
|
2017-08-23 17:53:06 +02:00
|
|
|
} else if (
|
|
|
|
property === 'angle' ||
|
|
|
|
property === 'width' ||
|
|
|
|
property === 'height' ||
|
|
|
|
property === 'depth'
|
|
|
|
) {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property, -1000, 1000, 1));
|
2017-08-23 17:53:06 +02:00
|
|
|
} else if (
|
|
|
|
property === 'near' ||
|
|
|
|
property === 'distanceGrain' ||
|
|
|
|
property === 'bumpScale' ||
|
|
|
|
property === 'envMapIntensity'
|
|
|
|
) {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property, -10, 100, 0.001));
|
2017-08-23 17:53:06 +02:00
|
|
|
} else if (
|
|
|
|
property === 'heightOffset' ||
|
|
|
|
property === 'rotationFactor'
|
|
|
|
) {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property, -100, 100, 0.001));
|
2017-08-23 17:53:06 +02:00
|
|
|
} else {
|
2017-08-24 22:20:40 +02:00
|
|
|
handles.push(folder.add(object, property, -10000, 10000, grain));
|
2017-08-23 17:53:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handles.map(
|
|
|
|
function(handle) {
|
2017-08-24 22:20:40 +02:00
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
if (property === 'name') {
|
|
|
|
handle.onFinishChange(
|
2017-08-24 22:20:40 +02:00
|
|
|
function(__handle, __folder) {
|
2017-08-23 17:53:06 +02:00
|
|
|
return function(value) {
|
2017-08-24 22:20:40 +02:00
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
componentTemplate.affected.map(
|
|
|
|
function(component){
|
|
|
|
component[property] = value;
|
|
|
|
component.updateInstance();
|
|
|
|
}
|
|
|
|
);
|
2017-08-24 22:20:40 +02:00
|
|
|
|
|
|
|
var li = __folder.domElement.getElementsByClassName('title')[0];
|
|
|
|
li.innerHTML = value;
|
2017-08-23 17:53:06 +02:00
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
}(handle, folder)
|
2017-08-23 17:53:06 +02:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
handle.onChange(
|
|
|
|
function (value) {
|
|
|
|
|
|
|
|
if (typeof this.initialValue === 'number') {
|
|
|
|
value = Number(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentTemplate.affected.map(
|
|
|
|
function(component){
|
|
|
|
component[property] = value;
|
|
|
|
component.updateInstance();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2017-08-24 22:20:40 +02:00
|
|
|
|
|
|
|
if (listen) {
|
|
|
|
handle.listen();
|
|
|
|
}
|
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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-22 19:18:14 +02:00
|
|
|
/**
|
2017-08-23 17:53:06 +02:00
|
|
|
* First, start fresh - remove all folders
|
2017-08-22 19:18:14 +02:00
|
|
|
*/
|
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-22 19:18:14 +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-22 19:18:14 +02:00
|
|
|
*/
|
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),
|
|
|
|
[]
|
|
|
|
);
|
|
|
|
}
|
2017-08-22 19:18:14 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sort the components by component type
|
|
|
|
*/
|
2017-08-23 17:53:06 +02:00
|
|
|
this.components.sort(
|
2017-08-22 19:18:14 +02:00
|
|
|
|
|
|
|
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(
|
2017-08-22 19:18:14 +02:00
|
|
|
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
|
|
|
|
2017-08-22 19:18:14 +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-22 19:18:14 +02:00
|
|
|
},
|
|
|
|
[
|
|
|
|
{
|
2017-08-23 17:53:06 +02:00
|
|
|
componentType : this.components[0].componentType,
|
2017-08-22 19:18:14 +02:00
|
|
|
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.
|
|
|
|
*/
|
2017-08-22 19:18:14 +02:00
|
|
|
componentGroups.map(
|
2017-06-29 15:23:50 +02:00
|
|
|
|
2017-08-22 19:18:14 +02:00
|
|
|
function(componentGroup){
|
|
|
|
|
|
|
|
if (componentGroup.components.length < 1) {
|
|
|
|
console.warn('invalid number of components');
|
2017-06-30 12:06:55 +02:00
|
|
|
}
|
2017-08-22 19:18:14 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-06-30 12:06:55 +02:00
|
|
|
if (
|
2017-08-22 19:18:14 +02:00
|
|
|
result.template[property] instanceof GameLib.Vector2 ||
|
|
|
|
result.template[property] instanceof GameLib.Vector3 ||
|
|
|
|
result.template[property] instanceof GameLib.Vector4
|
2017-06-30 12:06:55 +02:00
|
|
|
) {
|
2017-08-22 19:18:14 +02:00
|
|
|
if (!result.template[property].equals(component[property])) {
|
|
|
|
delete result.template[property];
|
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
2017-06-30 12:06:55 +02:00
|
|
|
}
|
2017-08-22 19:18:14 +02:00
|
|
|
|
|
|
|
if (result.template[property] !== component[property]) {
|
|
|
|
delete result.template[property];
|
|
|
|
}
|
2017-06-30 12:06:55 +02:00
|
|
|
}
|
|
|
|
}
|
2017-08-22 19:18:14 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 + '))';
|
2017-08-22 19:18:14 +02:00
|
|
|
} else {
|
|
|
|
name = componentTemplate.template.name;
|
2017-06-30 12:06:55 +02:00
|
|
|
}
|
|
|
|
|
2017-08-22 19:18:14 +02:00
|
|
|
var folder = gui.addFolder(name);
|
2017-06-30 12:06:55 +02:00
|
|
|
|
2017-08-22 19:18:14 +02:00
|
|
|
if (!folder) {
|
2017-08-23 17:53:06 +02:00
|
|
|
return;
|
2017-08-22 19:18:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2017-08-22 19:18:14 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector3) {
|
2017-08-23 17:53:06 +02:00
|
|
|
this.buildVectorControl(folder, componentTemplate, templateProperty, 3);
|
2017-08-22 19:18:14 +02:00
|
|
|
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);
|
2017-08-22 19:18:14 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
if (componentTemplate.template[templateProperty] instanceof Array) {
|
|
|
|
this.buildArrayManagerControl(folder, componentTemplate, templateProperty);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-08-24 22:20:40 +02:00
|
|
|
if (componentTemplate.template[templateProperty] instanceof GameLib.Color) {
|
|
|
|
this.buildColorControl(folder, componentTemplate, templateProperty);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
if (typeof componentTemplate.template[templateProperty] === 'object') {
|
2017-08-24 22:20:40 +02:00
|
|
|
|
|
|
|
if (componentTemplate.template[templateProperty] instanceof GameLib.Component) {
|
|
|
|
this.buildSelectControl(folder, componentTemplate, templateProperty)
|
|
|
|
} else {
|
|
|
|
//TODO: maybe start including some other types of objects
|
|
|
|
//console.log('ignored : ' + templateProperty);
|
|
|
|
}
|
2017-08-23 17:53:06 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.buildControl(folder, componentTemplate, templateProperty);
|
2017-08-22 19:18:14 +02:00
|
|
|
// 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-22 19:18:14 +02:00
|
|
|
);
|
2017-08-23 17:53:06 +02:00
|
|
|
}.bind(this));
|
2017-06-30 12:06:55 +02:00
|
|
|
|
2017-06-29 15:23:50 +02:00
|
|
|
};
|
|
|
|
|
2017-08-22 19:18:14 +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-22 19:18:14 +02:00
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
this.buildGUI(null);
|
2017-08-22 19:18:14 +02:00
|
|
|
};
|
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
GameLib.System.GUI.prototype.removeComponent = function(data) {
|
2017-06-30 12:06:55 +02:00
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
var index = this.backupComponents.indexOf(data.component);
|
|
|
|
if (index !== -1) {
|
|
|
|
this.backupComponents.splice(index, 1);
|
|
|
|
}
|
2017-06-30 12:06:55 +02:00
|
|
|
|
2017-08-23 17:53:06 +02:00
|
|
|
index = this.components.indexOf(data.component);
|
|
|
|
if (index !== -1) {
|
|
|
|
this.components.splice(index, 1);
|
|
|
|
}
|
2017-08-22 19:18:14 +02:00
|
|
|
|
|
|
|
};
|
|
|
|
|
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
|
|
|
});
|
|
|
|
|
2017-08-22 19:18:14 +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
|
|
|
};
|
|
|
|
|