Jump to content

Loading Asynchronous Objects into array for later use?


Aerion
 Share

Recommended Posts

Your way is not possible.

Think about it

var myMesh = [];

myMesh[0] = LoadEntity(entityname1, entitylocation1, entityfile1);

myMesh[0].rotation.y += 0.01;

The Javascript interpreter goes

myMesh = [ ]; OK I will set up the myMesh array

myMesh[0] = LoadEntity(entityname1, entitylocation1, entityfile1); OK I will start doing the loading of the named mesh and when finished will drop it into the myMesh array at position 0. While the loading is happening I will go on and do the next thing I am asked to

myMesh[0].rotation.y += 0.01; Not OK, cannot do this as I cannot find anything in the myMesh array it is just an empty array so I give up.

Link to comment
Share on other sites

7 hours ago, Mythros said:

I need to be able to load any number of different models at any time

How are you controlling the at any time?

Do you mean when a user decides to?

If so what will the user do to start the process of loading any number of different models at any time?

If not then please describe how you see the process of loading at any time.

Link to comment
Share on other sites

@Deltakosh I need help. As I said, I want to be able to store the mesh data in arrays & use the arrays as variables in later functions WITH OR without all this asychronous bullshit. I need a synchronous way to load models... This asynchonous crap has thrown my project off schedule by merely 3 weeks...

Thank you! <3

Link to comment
Share on other sites

Hi, @Deltakosh

Well I want the variable myMesh [ ] to hold the information of the meshes for use in other functions. Like the below : 

First, at the top of the file, define "myMesh" as a global object :: 

	var myMesh = [ ];
	

Then, in the createScene ( ) function :: 

	myMesh [ 0 ] = LoadEntity ( entityname1, entitylocation1, entityfile1 );
	myMesh [ 1 ] = LoadEntity ( entityname2, entitylocation2, entityfile2 );
	

Then in the UPDATE function OR OTHER functions, I want to be able to still have access to that CERTAIN mesh or those CERTAIN meshes ( by using a for loop as opposed to an assigned index ) :: 

	myMesh [ 0 ].rotation.y -= 0.01;
	myMesh [ 1 ].rotation.x += 0.01;
	

OR

	for ( var i = 0; i <= myMesh.length; i++ )

        {

            if ( i === 0 )

            {

                myMesh [ i ].rotation.x -= 0.01;

                myMesh [ i ].rotation.y += 0.01;

            }

            if ( i === 1 )

            {

                myMesh [ i ].rotation.y -= 0.01;

                myMesh [ i ].rotation.z += 0.01;

            }

        }

--------------

Whether that's Asynchronous or not, I don't care, I just need it done this way so I can reference ANY mesh in ANY function at ANY time in the code.

--------------

Thank You, @Deltakosh! <3

 

Link to comment
Share on other sites

@adam a brilliant solution that does what Mythros needs even if not in the form wanted. It is quite straightforward to get it into that form however with a bit of work. I did not think it was possible but then I did not know about the power of the assetsManager. Very well done adam.

Of course as DK has just stated Any time is not possible only any time after the meshes have been loaded.

@Mythros here is how you can develop adam's solution into one that is similar to the code in your last post. All references to lines are from  https://playground.babylonjs.com/#RAE99T#4

meshes array can of course by myMesh array if you want.

You will still need to set up the assetsManager and onFinish and load()

The LoadEntity  function can be formed from looking at the repetitive form of lines 15 to 21 and 23 to 28

Just pass in name, url stem and file name as wanted by addTask.

Instead of using names to allocate to the meshes array you can use a number but you will have to add this to the parameters for LoadEntity for each entity to load.

As you are now referring to meshes by number you can drop cloning altogether  and so you do not need the scene.removeMesh(task.loadedMeshes[??]); line as you need to keep each loaded mesh in meshes.

Then inside the start() function you have access to the meshes array so do all the scaling and positioning bits individually to meshes[0] and meshes[1] and the joint bits in the for loop for both meshes.

Give it ago and we will be all the more impressed even if it is not quite right the first time.

Link to comment
Share on other sites

7 hours ago, Mythros said:

@Deltakosh First I want to Load all entities with a function. Then, after they are loaded, I want to be able to affect them in other functions

and as I said in my previous post adam's solution essentially does this.

Lines 15 to 21 and 23 to 28 are part of  LoadEntity identifying the individual meshes to load.

Line 34  starts the loading.

Line 30 is - after they are all loaded start affecting them in other functions which are contained within the start function. Call the start function main if you prefer.

This can all be adapted to be written closer to the form you want, just follow the hints I gave you.

Even if your attempt to do so does not work I, for one, will respect you for trying and help you finishing it to look more like you want.

 

 

 

Link to comment
Share on other sites

...
if you feel like doing some reading and a little bit of work this is how I handled and loaded a ton of materials and preset objects into a huge city scene.
 

City.prototype.buildMaterials = function(){
	var materialList = [
	{
		name : 'Street_Cone_Color',
		type : 'jpg',
		material : 'standard',
		backface : true,
	},
    ...
	{
		name : 'Glass_1',
		type : 'basic',
		diffuseColor : new BABYLON.Color3(0.95, 0.95, 1.0),
		opacity : 0.45,
	},
	...
	...
	{
		name : 'concrete2',
		type : 'jpg',
		material : 'standard',
		backface : true,
	}
	
	
	
	
	];
	this.materialBank = {};
	this._buildMaterials(materialList, materialList.length);

	
};

City.prototype._buildMaterials = function(list, c){
	
	if(list.length>0){
		City.progressBar((c-list.length), c, "Building Materials");
		var mat = list.splice(0,1)[0];
		if(mat.material == 'standard'){
			mat.material = new BABYLON.StandardMaterial(mat.name, this.scene);
			mat.material.diffuseTexture = new BABYLON.Texture("./assets/Textures/"+mat.name+"."+mat.type, this.scene);
		
		if(mat.backface){
		mat.material.backFaceCulling = false;
		}
		if(mat.hasAlpha){
		mat.material.diffuseTexture.hasAlpha = true;
		}
		if(mat.opacity){
		mat.material.alpha = mat.opacity;
		}
		}else if(mat.maerial = 'basic'){
			mat.material = new BABYLON.StandardMaterial(mat.name, this.scene);
			if(mat.backface){
			mat.material.backFaceCulling = false;
			}
			if(mat.emissiveColor){
				mat.material.emissiveColor = mat.emissiveColor;
			}
			if(mat.diffuseColor){
				mat.material.diffuseColor = mat.diffuseColor;
			}
			if(mat.opacity){
			mat.material.alpha = mat.opacity;
			}
		}else if(mat.maerial = 'PBR'){
			mat.material = new BABYLON.PBRMaterial(mat.name, this.scene);
			if(mat.albedoColor){
				mat.material.albedoColor = mat.albedoColor;
			}
			if(mat.reflectivityColor){
				mat.material.reflectivityColor = mat.reflectivityColor;
			}
		}
		
		this.materialBank[mat.name] = mat;	
		var self = this;
		setTimeout(function(){self._buildMaterials(list,c);},0);
	}else{
		City.progressBar(-1);
		console.log('Material Bank Built!');
		console.log('------------------------------------');
		console.log(this.materialBank);
		console.log('------------------------------------');
		this.buildPresets();
	}
	
	
	
};

City.prototype.buildPresets = function(){
	var presetList = [
	{
		name : 'Street_Cone',
		dir : 'misc',
		materials : ['Street_Cone_Color'],
		scaleOnLoader : 15,
	},
	{
		name : 'Concrete_Street_Partition',
		dir : 'misc',
		materials : ['Concrete_Street_Partition_Color'],
		scaleOnLoader : 6,
	},

	...
		name : 'Bike_Type_1',
		dir : 'misc',
		materials : ['red_metal', 'aluminium', 'metaldark2', 'aluminium', 'metaldark2', 'aluminium', 'metaldark2', 'aluminium', 'metaldark2', 'aluminium', 'aluminium', 'blackmetal2', 'aluminium', 'blackmetal2','aluminium' ],
		scaleOnLoader : 6,
	
	},
	...
	{
		name : 'Foliage_Patch',
		dir : 'misc',
		materials : ['Foliage'],
		scaleOnLoader : 3.5,
	
	},
	...
	{
		name : 'Pay_Phone',
		dir : 'misc',
		materials : ['streetmisc', 'Plastic_Black'],
		scaleOnLoader : 5,
	
	},
	...
	{
		name : 'Street_Sign_Protest_Pike',
		dir : 'misc',
		materials : ['Street_Signs_Custom_2'],
		scaleOnLoader : 3.5,
	
	},
	...
	{
		name : 'Large_Construction_Site',
		dir : 'buildings',
		materials : ['concretedirty', 'streetmisc', 'cfence', 'blackmetal', 'Soil', 'streetsigns', 'metal_scratched', 'Doors', 'Roofmisc', 'constructionsite', 'MetalChrome', 'concretedark', 'Plastic_Black' ],
		scaleOnLoader : 0.25,
	
	},
	{
		name : 'Building_1',
		dir : 'buildings',
		materials : ['concrete', 'metaldark', 'concretedark', 'Glass_1', 'blackmetal', 'Glass_1'],
		scaleOnLoader : 0.2,
	
	},
	{
		name : 'Building_2',
		dir : 'buildings',
		materials : ['concrete_b', 'Glass_1', 'metaldark', 'Roofmisc', 'aluminium', 'rooftop2'],
		scaleOnLoader : 0.2,
	
	},
	{
	...
	{
		name : 'Building_7',
		dir : 'buildings',
		materials : ['Windows10', 'concrete_perforated2',  'rooftop2', 'metaldark', 'concretedark', 'wallbeige4',  'curtain', 'Roofmisc', 'streetmisc', 'aluminium', 'streetmisc2', 'concrete_b', 'concrete', 'blackmetal', 'Glass_1'],
		scaleOnLoader : 0.25,
	
	},
	...
	{
		name : 'Building_29',
		dir : 'buildings',
		materials : ['roof_floor', 'Glass_1', 'brickbrown11', 'concrete2', 'wallorange2', 'Windows3', 'shopfronts1', 'commercials3' , 'metal'],
		scaleOnLoader : 0.3,
	
	}
	
	
	
	
	
	];
	this.presetBank = {};
	this._buildPresets(presetList, presetList.length);
};

City.prototype._buildPresets = function(list, c){
	
		if(list.length>0){
		City.progressBar((c-list.length), c, "Building Presets");
		var preset = list.splice(0,1)[0];
		var newload = this.loader.addMeshTask("load_Preset", "", "./assets/"+preset.dir+"/", preset.name+".obj");
		
		var self = this;

		newload.onSuccess = function (task) {
			
			
			if(typeof self.presetBank[preset.name] == 'undefined'){
				if(self.lastPresetLoaded){
					self.presetBank[self.lastPresetLoaded].setEnabled(0);
					self.presetBank[self.lastPresetLoaded].parent = null;
					self.presetBank[self.lastPresetLoaded].scaling = new BABYLON.Vector3(1,1,1);
					self.presetBank[self.lastPresetLoaded].position = new BABYLON.Vector3(0,0,0);
				}
			
				if(task.loadedMeshes.length==1){
					
					var mesh = task.loadedMeshes[0];
					//console.log(mesh);
						mesh.renderingGroupId = 1;
						var positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
       					var indices = mesh.getIndices();
        				var normals = mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
       					mesh.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normals, true, true);
						BABYLON.VertexData.ComputeNormals(positions, mesh.getIndices(), normals);
						mesh.material = self.materialBank[preset.materials[0]].material;
						mesh.scaling = new BABYLON.Vector3(preset.scaleOnLoader, preset.scaleOnLoader, preset.scaleOnLoader);
						mesh.parent = self.presetPad;
						
					
						self.presetBank[preset.name] = mesh;
						self.lastPresetLoaded = preset.name;
					
			
			}else{
				var firstMesh = task.loadedMeshes[0];
				var chain = firstMesh.name.split(' ');
				var pMesh = new BABYLON.Mesh(chain[0], self.scene);
				console.log("Making Parent Preset Object "+chain[0]);			
				for(var i=0; i<task.loadedMeshes.length; i++){
						var childMesh = task.loadedMeshes[i];
						//console.log(childMesh);
						//console.log(pMesh);
						
						chain = childMesh.name.split(' ');
						childMesh.renderingGroupId = 1;
						childMesh.name = chain[chain.length-1];
						console.log("Making Child Object "+childMesh.name);
						var positions = childMesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
       					var indices = childMesh.getIndices();
        				var normals = childMesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
       					childMesh.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normals, true, true);
						BABYLON.VertexData.ComputeNormals(positions, childMesh.getIndices(), normals);
						childMesh.material = self.materialBank[preset.materials[i]].material;
						childMesh.parent = pMesh;
						console.log("Child Object Made");
						
				}
						pMesh.scaling = new BABYLON.Vector3(preset.scaleOnLoader, preset.scaleOnLoader, preset.scaleOnLoader);
						pMesh.parent = self.presetPad;
						
						
						self.presetBank[preset.name] = pMesh;
						self.lastPresetLoaded = preset.name;
						console.log("Set As Preset");
				}
			}
				
			
			setTimeout(function(){self._buildPresets(list,c);},10);
			
		};
		
		
		this.loader.load();
		this.loader.reset();

	}else{			
	
					this.presetBank[this.lastPresetLoaded].setEnabled(0);
					this.presetBank[this.lastPresetLoaded].parent = null;
					this.presetBank[this.lastPresetLoaded].scaling = new BABYLON.Vector3(1,1,1);
					this.presetBank[this.lastPresetLoaded].position = new BABYLON.Vector3(0,0,0);
		City.progressBar(-1);
		console.log('Preset Bank Built!');
		console.log('------------------------------------');
		console.log(this.presetBank);
		console.log('------------------------------------');
		this.startSceneLoad();
	}
	
};

the ... sections are where I cut out areas of the preset arrays to save on space on this post.  With this technique you can sync or async load the assets.  It can handle hundreds of models depending on their size and complexity in this example I ended up loading 80 some materials and over 200 some meshes with no performance impact.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...