Aerion Posted August 29, 2017 Author Share Posted August 29, 2017 Anyone else is more than welcome to answer this! I want this released to the community so other people don't have the same trouble I had while loading & manipulating models! <3 Thank You! <3 Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 29, 2017 Author Share Posted August 29, 2017 If you need more in-depth explanation, I can provide. Quote Link to comment Share on other sites More sharing options...
JohnK Posted August 29, 2017 Share Posted August 29, 2017 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. Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 29, 2017 Author Share Posted August 29, 2017 Then what is YOUR way? @JohnK Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 29, 2017 Author Share Posted August 29, 2017 Isn't there a way to load meshes NON-asynchronously? Asynchronous is a pain in ass. @Deltakosh Quote Link to comment Share on other sites More sharing options...
JohnK Posted August 29, 2017 Share Posted August 29, 2017 9 hours ago, Mythros said: i did try it the way you suggested. 8 minutes ago, Mythros said: Then what is YOUR way? ????????????????????? Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 29, 2017 Author Share Posted August 29, 2017 @JohnK https://www.babylonjs-playground.com/#1QJUDF%2333 Line 60 I did it the way you told me to & it's not working the way I need it to. I need to be able to load any number of different models at any time with 1 command and manipulate them with 1 other command. Quote Link to comment Share on other sites More sharing options...
JohnK Posted August 29, 2017 Share Posted August 29, 2017 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. Quote Link to comment Share on other sites More sharing options...
adam Posted August 29, 2017 Share Posted August 29, 2017 Why is it that you can't do something like this? https://playground.babylonjs.com/#RAE99T#1 Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 29, 2017 Author Share Posted August 29, 2017 Because I don't want to use a button. I WISH the damn model loader were Synchronous. Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 29, 2017 Author Share Posted August 29, 2017 Can you not return the data with a promise? If so, how? Quote Link to comment Share on other sites More sharing options...
adam Posted August 29, 2017 Share Posted August 29, 2017 51 minutes ago, Mythros said: Because I don't want to use a button. I WISH the damn model loader were Synchronous. The button is just for the demo. You can do the same thing without a button. https://playground.babylonjs.com/#RAE99T#4 Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 29, 2017 Author Share Posted August 29, 2017 Is there a way to store these meshes inside a returned promise? Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 30, 2017 Author Share Posted August 30, 2017 @adam What you posted is almost the type of functionality I need, but I wanna be able to return the data in a promise for use in other functions. Thank You! <3 Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 30, 2017 Author Share Posted August 30, 2017 @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 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 30, 2017 Share Posted August 30, 2017 Hello, I struggle to understand your issue. What is wrong with the demo that @adam created for you? Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 31, 2017 Author Share Posted August 31, 2017 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 Quote Link to comment Share on other sites More sharing options...
adam Posted August 31, 2017 Share Posted August 31, 2017 Change clones array in my example to myMesh. You most likely are going to want to use clones or instances for performance reasons. You could change cloneSkull and cloneLogo to one function that takes the entity name as a param. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 31, 2017 Share Posted August 31, 2017 You cannot do it at ANY time as you first need to wait for the meshes to be loaded You can start doing what you want with meshes in the "start" function in Adam's example (line #79). Quote Link to comment Share on other sites More sharing options...
JohnK Posted August 31, 2017 Share Posted August 31, 2017 @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. Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 31, 2017 Author Share Posted August 31, 2017 1 hour ago, JohnK said: Any time is not possible only any time after the meshes have been loaded. Quote Link to comment Share on other sites More sharing options...
Aerion Posted August 31, 2017 Author Share Posted August 31, 2017 The above quote is right, @JohnK that's what I've been trying to say. Quote Link to comment Share on other sites More sharing options...
Aerion Posted September 1, 2017 Author Share Posted September 1, 2017 @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 Quote Link to comment Share on other sites More sharing options...
JohnK Posted September 2, 2017 Share Posted September 2, 2017 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. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted September 2, 2017 Share Posted September 2, 2017 ... 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.