fucking image loading.... again..

beta.r3js.org
-=yb4f310 2017-08-15 22:26:12 +02:00
parent 37677c657d
commit 597191bf58
7 changed files with 259 additions and 21 deletions

View File

@ -51,6 +51,9 @@ GameLib.Event.MESH_DELETED = 0x23;
GameLib.Event.MESH_SELECTED = 0x24;
GameLib.Event.MESH_DESELECTED = 0x25;
GameLib.Event.COMPONENT_REGISTER = 0x26;
GameLib.Event.IMAGE_NOT_FOUND = 0x27;
GameLib.Event.BLENDER_DATA_RECEIVED = 0x28;
GameLib.Event.IMAGE_UPLOAD_COMPLETE = 0x29;
/**
* Subscribe to some events

View File

@ -650,4 +650,18 @@ GameLib.Utils.PushUnique = function(array, object) {
*/
GameLib.Utils.IsEmpty = function(obj) {
return (Object.keys(obj).length === 0 && obj.constructor === Object);
};
GameLib.Utils.LowerUnderscore = function(name) {
return name.toLowerCase().replace(/\s+/, '_');
};
GameLib.Utils.UpperCaseWordsSpaces = function(word) {
return word.replace(/[-_]/g, ' ').split(' ').reduce(
function(result, word) {
result += word[0].toUpperCase() + word.substr(1);
return result + ' ';
},
''
).trim();
};

View File

@ -2,6 +2,8 @@
* Image
* @param id
* @param name
* @param fileName
* @param extension
* @param path
* @param contentType
* @param size
@ -11,6 +13,8 @@
GameLib.D3.API.Image = function(
id,
name,
fileName,
extension,
path,
contentType,
size,
@ -22,12 +26,22 @@ GameLib.D3.API.Image = function(
this.id = id;
if (GameLib.Utils.UndefinedOrNull(name)) {
name = 'Image ' + GameLib.Utils.RandomId() + '.png';
name = 'Image ' + id;
}
this.name = name;
if (GameLib.Utils.UndefinedOrNull(path)) {
path = '/' + this.name.toLowerCase().replace(' ', '_');
if (GameLib.Utils.UndefinedOrNull(fileName)) {
fileName = GameLib.Utils.LowerUnderscore(name);
}
this.fileName = fileName;
if (GameLib.Utils.UndefinedOrNull(extension)) {
extension = '.unknown';
}
this.extension = extension;
if (GameLib.Utils.UndefinedOrNull(path)) {
path = '/';
}
this.path = path;
@ -35,15 +49,15 @@ GameLib.D3.API.Image = function(
contentType = 'application/octet-stream';
if (this.name.match(/(png)$/i)) {
if (this.extension.match(/(png)$/i)) {
contentType = 'image/png';
}
if (this.name.match(/(jpg|jpeg)$/i)) {
if (this.extension.match(/(jpg|jpeg)$/i)) {
contentType = 'image/jpeg';
}
if (this.name.match(/(gif)$/i)) {
if (this.extension.match(/(gif)$/i)) {
contentType = 'image/gif';
}
}
@ -72,6 +86,8 @@ GameLib.D3.API.Image.FromObject = function(objectImage) {
return new GameLib.D3.API.Image(
objectImage.id,
objectImage.name,
objectImage.fileName,
objectImage.extension,
objectImage.path,
objectImage.contentType,
objectImage.size,

View File

@ -8,6 +8,9 @@ GameLib.D3.Image = function(
graphics,
apiImage
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (GameLib.Utils.UndefinedOrNull(apiImage)) {
apiImage = {};
}
@ -20,6 +23,8 @@ GameLib.D3.Image = function(
this,
apiImage.id,
apiImage.name,
apiImage.fileName,
apiImage.extension,
apiImage.path,
apiImage.contentType,
apiImage.size,
@ -60,6 +65,8 @@ GameLib.D3.Image.prototype.toApiObject = function() {
var apiImage = new GameLib.D3.API.Image(
this.id,
this.name,
this.fileName,
this.extension,
this.path,
this.contentType,
this.size,

View File

@ -173,7 +173,7 @@ GameLib.D3.Texture.prototype.createInstance = function() {
);
instance.needsUpdate = true;
} else {
return null;
instance = new THREE.CubeTexture();
}
if (this.mapping !== GameLib.D3.Texture.TYPE_CUBE_REFLECTION_MAPPING &&
@ -190,7 +190,7 @@ GameLib.D3.Texture.prototype.createInstance = function() {
);
instance.needsUpdate = true;
} else {
return null;
instance = new THREE.Texture();
}
if (this.mapping !== GameLib.D3.Texture.TYPE_UV_MAPPING) {

View File

@ -24,6 +24,7 @@ GameLib.System.Linking = function(
this.resolved = [];
this.imageNotFoundSubscription = null;
this.componentCreatedSubscription = null;
this.parentSceneChangeSubscription = null;
this.parentEntityChangeSubscription = null;
@ -85,6 +86,10 @@ GameLib.System.Linking.prototype.start = function() {
this.materialInstanceCreated
);
this.imageNotFoundSubscription = this.subscribe(
GameLib.Event.IMAGE_NOT_FOUND,
this.imageNotFound
)
};
GameLib.System.Linking.prototype.link = function(component, data) {
@ -295,6 +300,44 @@ GameLib.System.Linking.prototype.componentCreated = function(data) {
this.resolveDependencies(component);
};
GameLib.System.Linking.prototype.imageNotFound = function(data) {
/**
* For blender files (and others) - we need to create the textures without images
*/
var textures = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Texture);
textures.map(function(texture){
/**
* data.image is a runtime image
*/
if (texture.image === data.image.id) {
/**
* This texture will never load because the image does not exist - so create
* its instance (without the image)
*/
texture.instance = texture.createInstance();
/**
* We override the 'loaded' value - we say its loaded because it will be just with defaults
* @type {boolean}
*/
texture.loaded = true;
GameLib.Event.Emit(
GameLib.Event.TEXTURE_INSTANCE_CREATED,
{
texture: texture
}
);
}
});
};
GameLib.System.Linking.prototype.meshInstanceCreated = function(data) {
this.resolveDependencies(data.mesh);
@ -421,21 +464,10 @@ GameLib.System.Linking.prototype.onParentEntityChange = function(data) {
data.newEntity.addComponent(data.object);
// - ok not so cool - we may have parent entities of entities -
// - so not all children should inherit the parent entity
// data.object.buildIdToObject();
//
// for (var property in data.object.idToObject) {
// if (data.object.idToObject.hasOwnProperty(property)) {
// if (data.object.idToObject[property].hasOwnProperty('parentEntity')) {
// data.object.idToObject[property].parentEntity = data.newEntity;
// }
// }
// }
};
GameLib.System.Linking.prototype.stop = function() {
this.imageNotFoundSubscription.remove();
this.componentCreatedSubscription.remove();
this.parentSceneChangeSubscription.remove();
this.parentEntityChangeSubscription.remove();

View File

@ -90,6 +90,8 @@ GameLib.System.Storage = function(
this.saveSubscription = null;
this.loadSubscription = null;
this.loadImageSubscription = null;
this.blenderDataSubscription = null
this.imageUploadCompleteSubscription = null;
};
GameLib.System.Storage.prototype = Object.create(GameLib.System.prototype);
@ -118,6 +120,16 @@ GameLib.System.Storage.prototype.start = function() {
GameLib.Event.LOAD_IMAGE,
this.loadImage
);
this.blenderDataSubscription = this.subscribe(
GameLib.Event.BLENDER_DATA_RECEIVED,
this.processBlenderData
);
this.imageUploadCompleteSubscription = this.subscribe(
GameLib.Event.IMAGE_UPLOAD_COMPLETE,
this.imageUploadComplete
);
};
/**
@ -452,6 +464,141 @@ GameLib.System.Storage.prototype.load = function(data) {
};
/**
* Once we have an image uploaded - we should load them all again - if their runtime version already exist, do nothing,
* otherwise, create the runtime version of it
* @param data
*/
GameLib.System.Storage.prototype.imageUploadComplete = function(data) {
var runtimeImages = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Image);
/**
* Process all images - we have to load them in addition to creating their runtime components
*/
data.images.map(function(imageData){
var image = runtimeImages.reduce(
function(result, runtimeImage){
if (imageData.id === runtimeImage.id) {
result = runtimeImage;
}
return result;
},
null
);
if (image) {
/**
* Do Nothing - the runtime version of this image already exists and simply needs to load
*/
} else {
/**
* We don't have this runtime version of the image - create it
* @type {GameLib.D3.Image}
*/
image = GameLib.D3.Image.FromObject(this.graphics, imageData);
}
/**
* Finally, load the image
*/
GameLib.Event.Emit(
GameLib.Event.LOAD_IMAGE,
{
image : image
}
);
}.bind(this));
};
/**
* Process Blender Data - Basically does what 'load' does - but because we already have the data we don't have
* a complicated load pattern - we create the runtime components in the best order we can (images load async unfortunately)
* and announce their creation so the linking system can link them
* @param data
*/
GameLib.System.Storage.prototype.processBlenderData = function(data) {
console.log('loading blender data');
/**
* Process all images - we have to load them in addition to creating their runtime components
*/
data.images.map(function(imageData){
var image = GameLib.D3.Image.FromObject(this.graphics, imageData);
GameLib.Event.Emit(
GameLib.Event.LOAD_IMAGE,
{
image : image
}
);
GameLib.Event.Emit(
GameLib.Event.COMPONENT_CREATED,
{
component: image
}
);
}.bind(this));
/**
* Process all textures
*/
data.textures.map(function(textureData){
var texture = GameLib.D3.Texture.FromObject(this.graphics, textureData);
GameLib.Event.Emit(
GameLib.Event.COMPONENT_CREATED,
{
component: texture
}
);
}.bind(this));
/**
* Process all materials
*/
data.materials.map(function(materialData){
var material = GameLib.D3.Material.FromObject(this.graphics, materialData);
GameLib.Event.Emit(
GameLib.Event.COMPONENT_CREATED,
{
component: material
}
);
}.bind(this));
/**
* Now process all meshes
*/
data.meshes.map(function(meshData){
var mesh = GameLib.D3.Mesh.FromObject(this.graphics, meshData);
GameLib.Event.Emit(
GameLib.Event.COMPONENT_CREATED,
{
component: mesh
}
);
}.bind(this));
/**
* And that should be it...
*/
};
GameLib.System.Storage.prototype.loadImage = function(data) {
console.log('loading image : ' + data.image.name);
@ -464,7 +611,7 @@ GameLib.System.Storage.prototype.loadImage = function(data) {
var image = data.image;
var url = this.apiUploadUrl + image.path + '?ts=' + Date.now();
var url = this.apiUrl + image.path + image.fileName + image.extension + '?ts=' + Date.now();
var preflight = new XMLHttpRequest();
@ -496,12 +643,29 @@ GameLib.System.Storage.prototype.loadImage = function(data) {
var url = window.URL.createObjectURL(this.response);
} else {
if (onError) {
GameLib.Event.Emit(
GameLib.Event.IMAGE_NOT_FOUND,
{
image : image
}
);
onError(image, {message:'Image not found'});
return;
}
}
} catch (error) {
if (onError) {
GameLib.Event.Emit(
GameLib.Event.IMAGE_NOT_FOUND,
{
image : image
}
);
onError(image, {message:'Image not found'});
return;
}
@ -570,5 +734,7 @@ GameLib.System.Storage.prototype.stop = function() {
this.loadSubscription.remove();
this.saveSubscription.remove();
this.loadImageSubscription.remove();
this.blenderDataSubscription.remove();
this.imageUploadCompleteSubscription.remove();
};