Jump to content

How does one implement automatic loading of a sub-region of a map, and the objects within it?


3556
 Share

Recommended Posts

As a part of evaluating Babylon.js, I’m trying to create a simple prototype of a first person game. It would consist of a square region/map (i.e. a square mesh with a basic texture) that is divided into 4 sub-regions (or, tiles) of equal size. Think of it as Tile1 to Tile4. Each tile consist in it one 3D cube (a cube mesh with a basic texture). The player (the camera object) moves from one tile to the next, and that tile & cube to where the player moves to, then become visible to the player. Attached an image depicting this.

On this, I had a question and would appreciate if anyone could answer.

How does one implement “automatic streaming & loading of assets” in Bablylon.js? In this prototype, the game would start out by player being, say, on Tile1 and Cube1 being visible. Other tiles & cubes aren’t yet visible. As the player moves and nears the boundary of Tile1, the other tile (say, Tile2) becomes visible - in a sort of fade-in effect.  As the player crosses into Tile2, the Tile2 region and Cube2 becomes visible (Tile1 & Cube1 slowly fade out).

Additionally, the non-visible assets (Tile2, 3 & 4 and Cube2, 3 & 4) are not yet present in the client/browser's memory (or disk). They would be "streamed" from the server to the browser only when the Player nears them. e.g. in the above case, as the Player nears the boundary of Tile1, only then the meshes/textures for Tile2 and Cube2 would be streamed from the sever to the browser.

Essentially, how does one achieve streaming & loading of a sub-regions of a map and objects that are in viewing distance of a Player? As the user traverses, other sub-region and objects start getting streamed in and loaded automatically, and become visible to the Player – in a seamless way?

One strategy I could think of was getting the Player's coordinates with reference to the coordinates of the Tile2 & Cube2, and computing the distance between them. When the distance becomes less than a specific threshold, send an event to the server to stream Tile2 & Cube2 assets. But am not sure if this could be done, or if this is the best way to implement it.

Any pointers/tutorial/references would be helpful. The “incremental loading” section of the documentation wasn’t explicit as to how this could be implemented. http://doc.babylonjs.com/tutorials/Using_the_Incremental_Loading_System

Wasn’t able to find an answer in any of the forum posts as well. 

TIA.
 

Babylon.js.PNG

Link to comment
Share on other sites

inspiration:

https://www.jouer.org/adept-beta.html

https://www.jouer.org/jsbb/2016.1.js

(working with firefox, i've discovered this morning that chrome is not loading)

but:

i've created tiles with ground function lacaze()

i'm populating it with map()

each emement is parented to terrain[]

players are not parented ^^.

i "ground" 9 tiles and populat 4 sides.

I have to complete it with dispose (easier with parenting)

Link to comment
Share on other sites

Thanks for your response. I'm still new to BJS & its APIs, and wasn't able to understand the functionality of lacaze() w.r.t. how it could be used to stream objects. Would appreciate if you could possibly provide a bit more details about it? 

Essentially, what I would be looking for is to get a list of assets (meshes & textures) with a specific radius of the camera object. That way I can have the sever stream those objects to the browser client. Is there any class or its methods that achieve this?

Link to comment
Share on other sites

lacase just create a ground square.

tou is the region name

var tou=GX+"-"+GY;

the ajax function just load a "heightMap" number. so you can specify différents jpg files to use with heightmap

created grounds are stored in terrains[]

terrains[tou].addLODLevel(125, null);

addLODlevel say that it will be visible only if you camera is less than 125 far.

here you only have sand squares.

Those squares are populated with map(); this is where you will define objects that you will put on squares

 

Link to comment
Share on other sites

In my opinion, if you do not want to load all your meshes at start, but streamed by the server, you should at least define their position in the 3D world, to know when you will have to stream it.
You can create an array storing the positions of your invisible objects :

var meshesPos = [];
meshesPos[0] = {x: 0, y: 0, z: 0};
meshesPos[1] = {x: 5, y: 0, z: 5};
meshesPos[2] = {x: 10, y: 2, z: 10};

After that, you can create a function which will check distance between your camera and the invisible meshes.

var checkDistance = function()
{
    for(var i=0; i<meshesPos.length; i++)
    {
        if(distance(meshesPos[i], camera.position) > STREAM_DISTANCE) {
            // Ask server to stream the corresponding object
        }
    }
}

The distance() function between A and B positions can be something very simple, like Pythagore theorem :

var distance = function(a, b)
{
    return sqrt( pow(a.x - b.x, 2) + pow(a.y - b.y, 2) + pow(a.z - b.z, 2) );
}

I don't even know if this is mathematically correct :o but you can use the distance function you want ;)

 

So now you have your checkDistance() function, you have to call it very often, to verify if you have to load meshes or not :

  • execute every frame : scene.registerBeforerender(checkDistance)
  • execute every X milliseconds : window.setInterval(checkDistance, X)

As I'm not so well informed about global performance I do not know which solution is better. For my part I prefer to use the second one and adjust it if necessary.

Link to comment
Share on other sites

Thanks, Pouet. I think that logic would work. Much appreciate. On the checkDistance() function, I was thinking it could be called every time there is a movement in the camera (i.e. its position changes). Time to try this out and see how it comes out! :-)

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...