Sparky Posted July 29, 2015 Share Posted July 29, 2015 Hi, I was just wondering how, in theory, you could incrementally load part of a scene that is changed in game and saved out? i.e. Load map, build things, save map. I've read the docs and seen that there is a way to do incremental loading, but that is using a piece of software that I won't have on the server. Can I save out the blocks of the scene into a certain json format? Thanks for your help Quote Link to comment Share on other sites More sharing options...
JohnK Posted July 29, 2015 Share Posted July 29, 2015 If by block you mean a mesh RaananW is working on saving a mesh or an array of meshes for BJS 2.2 you will then be able to use ImportMesh to load one or more of them at a time. Quote Link to comment Share on other sites More sharing options...
Sparky Posted July 30, 2015 Author Share Posted July 30, 2015 Thanks. Yeh, by block, I mean a merged mesh. How would that work with incremental loading though? Do we know if will be able to save out to a .incremental.babylon or just a .babylon? I can't seem to find any spec that states the difference between the two. Quote Link to comment Share on other sites More sharing options...
JohnK Posted July 31, 2015 Share Posted July 31, 2015 Have you read this topic http://www.html5gamedevs.com/topic/15024-how-to-displayrender-meshes-being-loaded-in-live/?hl=incremental#entry85151 Which leads you to the tools to convert .babylon to .incremental.babylon? Quote Link to comment Share on other sites More sharing options...
Sparky Posted July 31, 2015 Author Share Posted July 31, 2015 Yes, I've read that one. It links to source code for what looks like a C# project. It doesn't seem to have the spec for the .incremental.babylon files etc, which would be helpful (unless I've missed something). I'm not going to have those incremental files pre-built, so it doesn't look like that will be useful. I could always fight my way thought and refactor the code, but I was hoping that there was another option as I don't have Visual Studio on my home dev machine. Quote Link to comment Share on other sites More sharing options...
Sparky Posted July 31, 2015 Author Share Posted July 31, 2015 Didn't notice the bit about the GeometryID and the snippet about the incremental format in that thread. I'll have a play with that . Quote Link to comment Share on other sites More sharing options...
RaananW Posted July 31, 2015 Share Posted July 31, 2015 Hi!Just a note, incremental loading is triggered when the object is in the frustum (when it is seen by the camera). I wouldn't use it to load data after, for example, a new level is supposed to be shown.As John said, you could use the ImportMesh to do that, or the Append method of the loader (which loads cameras and lights as well as meshes).Incremental is automated, as I understand, you want to trigger it by yourself. Or am I way wrong here? Quote Link to comment Share on other sites More sharing options...
Sparky Posted July 31, 2015 Author Share Posted July 31, 2015 Hi Raanan, Thanks for your message. What I'm looking at is a shared map where users will have incrementally loaded sections, so I wouldn't be looking to trigger the incremental sections in that manner. But as the world is updated, I'll need to save out the updated sections for other users to load in. I will also be looking to save out and load in sections during gameplay while they are in the frustum i.e. if another player updates that section of the map. So from what you're saying, if I understand correctly, is that I should use incremental loading in the first instance (loading sections of map as the player moves around), but importMesh in the second instance (loading in a section of map from the server that has been updated by another player). Does that make sense? Quote Link to comment Share on other sites More sharing options...
reddozen Posted July 31, 2015 Share Posted July 31, 2015 Control the loads manually using import mesh.... I do this with a game client I'm working on. I use PHP and Ajax to dynamically build maps based on databased coordinates etc. I think what you're expecting incremental loading to be is not what you think. You will need a server engine to coordinate all the individual player changes, a heart beat from the clients to check for updates with the server, and an AJAX process to call import mesh from the server's list of new objects (or delete objects etc...). I hope this makes since to you. Quote Link to comment Share on other sites More sharing options...
Sparky Posted August 3, 2015 Author Share Posted August 3, 2015 Thanks Reddozen, That sounds pretty sensible. I'm just not sure what incremental loading is for then if I can't use it for that. But if what you're saying will work, then that's all good for me . Quote Link to comment Share on other sites More sharing options...
reddozen Posted August 3, 2015 Share Posted August 3, 2015 I pass it the babylon scene and then make my import mesh calls on it. Can make one to delete objects too... I have all my objects in specific babylon "packages". All my trees etc are in one babylon file, and map specific items are in another. You can use an array of items in import mesh to only load what you want out of the babylon file. I use this is organize my babylon files without having one for each object. Here's the main file I have... (looks like I have some stray marks to clean out of the dynamic function)http://www.diviniaro.com/WGClient/Models/Loaders/map_loader.php This is when I call a specific area of the map...http://www.diviniaro.com/WGClient/Models/Loaders/map_loader.php?zone=1®ion=1 Quote Link to comment Share on other sites More sharing options...
Sparky Posted August 4, 2015 Author Share Posted August 4, 2015 Cheers red, I'll take a look at the code. Much appreciated! Quote Link to comment Share on other sites More sharing options...
reddozen Posted August 4, 2015 Share Posted August 4, 2015 Here is the actual page if this helps. You'll see that it's a very short script, but build dynamic load lists based on groups of 3D objects loaded from a database.I group them by zone and region, and in the future will include sub-zones. The goal of my setup is eventually micro-managing the environment to minimize the amount of objects loaded. There's no reason to load everything in a house on the other side of town if you're not even near the building.<?php header('Content-type: text/javascript'); include("./database.php"); $region=$_GET['region']; $zone=$_GET['zone']; $file_type = "Raw"; $home_path = ".."; //create an array for the LOD scripts unset($LOD); list($res) = get_query("SELECT * FROM `lod_levels` ORDER BY `level`;"); while ($lodv = mysql_fetch_array($res)) { if ($lodv['level']!=1) { $LOD[$lodv['level']] = $LOD[$lodv['level']-1] .", { quality: ". $lodv['percent'] .", distance: ". $lodv['distance'] ." }"; } else { $LOD[$lodv['level']] = "{ quality: ". $lodv['percent'] .", distance: ". $lodv['distance'] ." }"; } } echo "var Prt_f01_map = function(scene, offset, DBObj){"; $last_obj=""; list($res) = get_query("SELECT * FROM `objects` LEFT JOIN `map_info` ON `objects`.`name`=`map_info`.`name` WHERE `region`=". $region ." && `zone`=". $zone ." ORDER BY `package`, `objects`.`name`;"); $count=0; while ($objects = mysql_fetch_array($res)) { if ($last_package!=$objects['package']) { if ($last_package!="") { echo "];"; $count=0; } echo " // package meshes var package_". $objects['package'] ." = ["; } if ($last_obj!=$objects['name']) { if ($count>0) { echo ", "; } echo "\"". $objects['name'] ."\""; $count++; } $last_package = $objects['package']; $last_obj = $objects['name']; } echo "];"; $last_package=""; $last_obj=""; mysql_data_seek($res, 0); while ($objects = mysql_fetch_array($res)) { if ($last_package!=$objects['package']) { if ($last_package!="") { echo " } } } );"; } echo " BABYLON.SceneLoader.ImportMesh(package_". $objects['package'] .", \"". $home_path . $objects['dir'] . $file_type ."/". $objects['package'] ."/\", \"". $objects['package'] .".babylon\", scene, function(mapZone, particleSystems, skeletons) { for (var i=0; i<mapZone.length; i++) {"; } if ($last_obj!=$objects['name']) { if ($last_obj!="" && $last_package==$objects['package']) { echo " }"; } echo " if (mapZone[i].name == \"". $objects['name'] ."\") { item_used=1; var ". $objects['name'] ."_inst = 0; mapZone[i].visiblity=true; mapZone[i].isVisible=true; mapZone[i].name = \"". $objects['name'] ."\"; mapZone[i].position = new BABYLON.Vector3(". $objects['px'] .", ". $objects['py'] .", ". $objects['pz'] ."); mapZone[i].scaling = new BABYLON.Vector3(". $objects['sx'] .", ". $objects['sy'] .", ". $objects['sz'] ."); mapZone[i].rotationQuaternion = null; mapZone[i].rotation = new BABYLON.Vector3(". $objects['rx'] .", ". $objects['ry'] .", ". $objects['rz'] ."); mapZone[i].backFaceCulling = false; mapZone[i].isPickable = true; DBObj[mapZone[i].name] = { ID: ". $objects['object_id'] .", Name: \"". $objects['name'] ."\", px: \"". $objects['px'] ."\", py: \"". $objects['py'] ."\", pz: \"". $objects['pz'] ."\", rx: \"". $objects['rx'] ."\", ry: \"". $objects['ry'] ."\", rz: \"". $objects['rz'] ."\", sx: \"". $objects['sx'] ."\", sy: \"". $objects['sy'] ."\", sz: \"". $objects['sz'] ."\" };"; if ($objects['lod']!=0) { echo " mapZone[i].simplify([". $LOD[$objects['lod']] ."], true, BABYLON.SimplificationType.QUADRATIC, function() { // we're not using the callback function for now...but it's here });"; } echo " //////////////////////////////////////////////////////// // Instance Copies ////////////////////////////////////////////////////////"; } else { echo " ". $objects['name'] ."_inst++; objInstance = mapZone[i].createInstance(\"". $objects['name'] ."_inst_\"+ ". $objects['name'] ."_inst +\"\"); objInstance.visible = true; objInstance.isVisible = true; objInstance.position = new BABYLON.Vector3(". $objects['px'] .", ". $objects['py'] .", ". $objects['pz'] ."); objInstance.scaling = new BABYLON.Vector3(". $objects['sx'] .", ". $objects['sy'] .", ". $objects['sz'] ."); objInstance.rotationQuaternion = null; objInstance.rotation = new BABYLON.Vector3(". $objects['rx'] .", ". $objects['ry'] .", ". $objects['rz'] ."); objInstance.backFaceCulling = false; objInstance.isPickable = true; DBObj[objInstance.name] = { ID: ". $objects['object_id'] .", Name: \"". $objects['name'] ."\", px: \"". $objects['px'] ."\", py: \"". $objects['py'] ."\", pz: \"". $objects['pz'] ."\", rx: \"". $objects['rx'] ."\", ry: \"". $objects['ry'] ."\", rz: \"". $objects['rz'] ."\", sx: \"". $objects['sx'] ."\", sy: \"". $objects['sy'] ."\", sz: \"". $objects['sz'] ."\" };"; } $last_package=$objects['package']; $last_obj=$objects['name']; } echo " } } } );}";?> Quote Link to comment Share on other sites More sharing options...
Sparky Posted August 5, 2015 Author Share Posted August 5, 2015 Thanks Red, What I had been looking at (from another forum members suggestion) was generating the map and then sectioning it off into merged meshes. Once I have the merged meshes, I'll save those out so I can just load a section of map (terrain, buildings and any other static elements) as required once visible to the user. If I'm understanding you correctly, your approach is to save out each map square/building/whatever else and load in a regions worth when required, which you'll then merge once it's all client side, is that right? Your approach would certainly be easier to manage across multiple users, but more work for babylon (as you'd be repeatedly merging the meshes. Not sure which is the best way to go. Quote Link to comment Share on other sites More sharing options...
reddozen Posted August 5, 2015 Share Posted August 5, 2015 I don't merge meshes. They're still individual objects. I want to avoid this when I can so that maps can be manipulated in real time by an admin, or for an event. My planned structure...Skybox - always loaded Zone - my local segment of the world map with landmarks and terrainTerrain - always loaded with LODLandmark objects - A ridiculous view distance and LOD Region - subsets of the zone. These have the buildings, trees, and other map fillers that I only want visible from a moderate view range. Rub-region - these are things like building interiors or dungeon crawler rooms. I don't want to render every cup, plate, and interior house detail if you're not inside the house, nor to I want to render every room of a large castle etc. From inside this area, I can also shut off all the other outside objects because you can't see the sky or buildings etc from inside a building. Quote Link to comment Share on other sites More sharing options...
Sparky Posted August 5, 2015 Author Share Posted August 5, 2015 Ah ok, are you building something first person then? I'm looking at at RTS, so could end up with a lot of meshes, which from what i've read, can be problematic and cause performance issues, hence the merging. You can get around the manipulation by keeping data and un-merging when needed in order to manipulate, then re-merge. These evens would be reasonably rare for me such as building something, so I wouldn't need it to be super-real-time as you might with say, picking up a cup. Quote Link to comment Share on other sites More sharing options...
reddozen Posted August 5, 2015 Share Posted August 5, 2015 I'm building an MMO environment. Things will added or removed from the render list based on distances to target and movement speed of the character. I'm sure I'll get into merging things once I've exhausted everything else. I use a lot of instancing though. 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.