parent scenes change - helpers are now components - intersects are now per scene / camera and sorted to distance

beta.r3js.org
-=yb4f310 2017-06-04 14:36:13 +02:00
parent f9c18837e6
commit d7a6185e46
7 changed files with 232 additions and 35 deletions

View File

@ -16,6 +16,7 @@ GameLib.Event.Subscriptions = {};
*/
GameLib.Event.WINDOW_RESIZE = 0x1;
GameLib.Event.PARENT_SCENE_CHANGE = 0x2;
GameLib.Event.PARENT_ENTITY_CHANGE = 0x3;
/**
* Subscribe to some events

View File

@ -17,6 +17,11 @@ GameLib.D3.Helper = function(
this.graphics = graphics;
this.graphics.isNotThreeThrow();
GameLib.Component.call(
this,
GameLib.Component.COMPONENT_HELPER
);
if (GameLib.Utils.UndefinedOrNull(id)) {
id = GameLib.Utils.RandomId();
}
@ -67,6 +72,9 @@ GameLib.D3.Helper = function(
this.instance = this.createInstance();
};
GameLib.D3.Helper.prototype = Object.create(GameLib.Component.prototype);
GameLib.D3.Helper.prototype.constructor = GameLib.D3.Helper;
/**
* Helper types
* @type {string}

View File

@ -191,12 +191,30 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager)
var cameras = entity.getComponents(GameLib.D3.Camera);
var scenes = entity.getComponents(GameLib.D3.Scene);
var meshes = entity.getComponents(GameLib.D3.Mesh);
var intersects = cameras.reduce(
function(result, camera){
var scene = scenes.reduce(
function(result, scene) {
if (scene.activeCamera === camera) {
result = scene;
}
return result;
},
null
);
if (scene) {
meshes = scene.meshes;
}
this.raycaster.instance.setFromCamera(
this.mouse,
camera.instance
@ -206,14 +224,34 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager)
intersects.map(function(intersect){
result.push(intersect);
})
});
return result;
}.bind(this),
[]
);
if (intersects.length > 0) {
intersects.sort(
function(a, b) {
if (a.distance < b.distance) {
return -1;
}
if (a.distance > b.distance) {
return 1;
}
return 0;
}
);
meshes = intersects.map(function(intersect){
return intersect.mesh;
});
var mesh = meshes[0];
if (mesh) {
/**
* Prevent default action (like context menu or whatever)
@ -229,7 +267,7 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager)
* Notify our component as being 'selected'
* @type {boolean}
*/
intersects[0].selected = !intersects[0].selected;
mesh.selected = !mesh.selected;
/**
* Add a helper to the scene
@ -237,53 +275,47 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager)
*/
var helper = null;
var scene = intersects[0].parentScene;
var scene = mesh.parentScene;
if (!scene) {
console.warn('the scene object for this mesh could not be located : ' + intersects[0].name);
console.warn('the scene object for this mesh could not be located : ' + mesh.name);
return;
}
var gui = entity.getFirstComponent(GameLib.GUI);
if (intersects[0].selected) {
if (mesh.selected) {
helper = new GameLib.D3.Helper(
this.graphics,
null,
intersects[0].name + ' Helper',
intersects[0],
mesh.name + ' Helper',
mesh,
GameLib.D3.Helper.HELPER_TYPE_EDGES
);
/**
* Backup the polygonOffset value, then set it to 'true' - helps for clear nice outlines
*/
intersects[0].polygonOffset = intersects[0].instance.material.polygonOffset;
mesh.polygonOffset = mesh.instance.material.polygonOffset;
intersects[0].instance.material.polygonOffset = true;
mesh.instance.material.polygonOffset = true;
entity.addComponent(helper);
scene.instance.add(helper.instance);
scene.subscribe(GameLib.Event.PARENT_SCENE_CHANGE, function(data) {
if (data.old === scene) {
scene.instance.remove(helper.instance);
}
});
gui.addObject(intersects[0]);
gui.addObject(mesh);
} else {
gui.removeObject(intersects[0]);
gui.removeObject(mesh);
var components = entity.getComponents(GameLib.D3.Helper);
helper = components.reduce(
function(result, component) {
if (component.object === intersects[0]) {
if (component.object === mesh) {
result = component;
}
return result;
@ -298,12 +330,12 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager)
/**
* Restore the polygonOffset value
*/
intersects[0].instance.material.polygonOffset = intersects[0].polygonOffset;
mesh.instance.material.polygonOffset = mesh.polygonOffset;
entity.removeComponent(helper);
} else {
console.warn('failed to locate helper object which should exist for ' + intersects[0].name);
console.warn('failed to locate helper object which should exist for ' + mesh.name);
}
}

View File

@ -163,7 +163,12 @@ GameLib.D3.Raycaster.prototype.getIntersectedObjects = function(meshes) {
meshes.map(
function(mesh){
if (mesh.instance === intersect.object){
result.push(mesh);
result.push(
{
mesh : mesh,
distance : intersect.distance
}
);
}
}
);

View File

@ -64,6 +64,8 @@ GameLib.EntityManager = function(
this.buildIdToObject();
this.instance = this.createInstance();
this.registerCallbacks();
};
GameLib.EntityManager.prototype = Object.create(GameLib.API.EntityManager.prototype);
@ -104,6 +106,54 @@ GameLib.EntityManager.prototype.createEntity = function(name) {
return entity;
};
/**
* Returns an entity by ID or null
* @param id
* @returns {*}
*/
GameLib.EntityManager.prototype.findEntityById = function(id) {
return this.entities.reduce(
function(result, entity){
if (entity.id === id) {
result = entity;
}
return result;
},
null
);
};
GameLib.EntityManager.prototype.findHelperByObject = function(object) {
return this.entities.reduce(
function(result, entity) {
var helpers = entity.getComponents(GameLib.D3.Helper);
var helper = helpers.reduce(
function(helperResult, tmpHelper) {
if (tmpHelper.object === object) {
helperResult = tmpHelper;
}
return helperResult;
},
null
);
if (helper) {
result = helper;
}
return result;
},
null
);
};
/**
* Adds an entity to this manager
* @param entity GameLib.Entity
@ -258,6 +308,86 @@ GameLib.EntityManager.FromObjectEntityManager = function(graphics, objectEntityM
return entityManager;
};
GameLib.EntityManager.prototype.onParentSceneChange = function(data) {
if (data.object instanceof GameLib.D3.Mesh) {
/**
* We remove the helper (if any) from the old scene and add it to the new scene
*/
var helper = this.findHelperByObject(data.object);
if (helper) {
data.originalScene.instance.remove(helper.instance);
data.newScene.instance.add(helper.instance);
}
/**
* We remove the mesh from the old scene and add it to the new scene
*/
data.originalScene.removeMesh(data.object);
data.newScene.addMesh(data.object);
/**
* We inherit the parent entity of this new scene
*/
var originalEntity = null;
var newEntity = null;
if (data.object.hasOwnProperty('parentEntity')) {
originalEntity = data.object.parentEntity
}
if (data.newScene.hasOwnProperty('parentEntity')) {
newEntity = data.newScene.parentEntity;
}
if (originalEntity && newEntity) {
/**
* We also transfer the helper (as a component) to the new entity
*/
if (helper) {
originalEntity.removeComponent(helper);
newEntity.addComponent(helper);
}
originalEntity.removeComponent(data.object);
newEntity.addComponent(data.object);
/**
* Now also remove the object from the GUI
*/
var gui = originalEntity.getFirstComponent(GameLib.GUI);
if (gui) {
gui.removeObject(data.object);
gui.build(this);
gui = newEntity.getFirstComponent(GameLib.GUI);
if (gui) {
gui.addObject(data.object);
gui.build(this);
}
}
}
}
if (data.object instanceof GameLib.D3.Light) {
console.log('implement remove light here');
}
};
/**
*
*/
GameLib.EntityManager.prototype.registerCallbacks = function() {
this.subscribe(
GameLib.Event.PARENT_SCENE_CHANGE,
this.onParentSceneChange
)
};
/**
* Links object Ids to actual objects
* @param idToObject

View File

@ -764,10 +764,10 @@ GameLib.GUI.prototype.buildSelectControl = function(folder, object, property, en
GameLib.Event.Emit(
GameLib.Event.PARENT_SCENE_CHANGE,
{
old: this.initialValue,
current: object[property],
originalScene: this.initialValue,
newScene: object[property],
object: object,
property: property
entityManager: entityManager
}
);
} else {
@ -841,12 +841,20 @@ GameLib.GUI.prototype.buildEntitySelectionControlFromArray = function(
);
folder.add(object, property, options).name(property).listen().onChange(
function(value) {
GameLib.Event.Emit(
GameLib.Event.PARENT_ENTITY_CHANGE,
{}
);
}
function(entityManager) {
return function(value) {
GameLib.Event.Emit(
GameLib.Event.PARENT_ENTITY_CHANGE,
{
originalEntity : this.initialValue,
newEntity : entityManager.findEntityById(value),
object : object
}
);
};
}(entityManager)
);
};
@ -884,12 +892,20 @@ GameLib.GUI.prototype.build = function(entityManager) {
var apiObject = object.toApiObject();
var folder = null;
try {
var folder = this.instance.addFolder(apiObject.name);
folder = this.instance.addFolder(apiObject.name);
} catch (e) {
//todo increase name count
console.log(e.message);
apiObject.name += GameLib.Utils.RandomId(3);
folder = this.instance.addFolder(apiObject.name);
}
if (!folder) {
throw new Error('Could not create folder');
}
var property;
for (property in apiObject) {

View File

@ -204,8 +204,13 @@ GameLib.Utils.Raycast = function (
* @returns {string}
* @constructor
*/
GameLib.Utils.RandomId = function() {
return Math.random().toString(36).substr(2, 10);
GameLib.Utils.RandomId = function(length) {
if (GameLib.Utils.UndefinedOrNull(length)) {
length = 10;
}
return Math.random().toString(36).substr(2, length);
};
GameLib.Utils.InvertWindingOrder = function(triangles) {