Balupg

Keeping canvas responsive

Recommended Posts

Hi all, I am revisiting Babylonjs after a long gap. Things have changed drastically in the last year (for good :) ) and hence I have a newbie question,

I am trying to utilise Babylonjs to give visual feedback to the user on his choice of designs. This involves creating a few hole patterns on flat plates based on an algorithm. After going through a few different approaches, I have stumbled upon the solid particle system where I could create cylinders to represent my pattern and display to the users. The cylinder locations are calculated using an external algorithm returned via ajax call and typically ends up creating 40,000 cylinders. Once the creation is completed, the performance is very good with 60fps.

The help I need is in keeping the interactiveness ongoing while the SPS is being added in the background and progress displayed to the user. Somehow not much webgl interaction is possible,  while the SPS Mesh is being constructed and the initparticles loop is running in my ajax call. I have tried to break it down into smaller batches, but not much luck.

Any suggestions would be much appreciated.

Regards,

Balu

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

Here is the code I am using. pointsData is an array of X and Y values and has ~1000 points in each bach - totalling around 40,000

$.ajax({

...

...

},

success: function(pointsData) {

var holeMesh = BABYLON.MeshBuilder.CreateCylinder("Hole", { diameterTop: holeDia, diameterBottom: holeDia, height: thickness + 0.001 }, sc);

                    var SPS = new BABYLON.SolidParticleSystem('SPS' , sc, { updatable: false });
                    SPS.billboard = false;
                    SPS.computeParticleRotation = false;
                    SPS.computeParticleColor = false;
                    SPS.computeParticleTexture = false;
                    SPS.computeBoundingBox = true;


                    SPS.addShape(holeMesh, pointsData.length);
                    var SPSMesh = SPS.buildMesh();
                    SPSMesh.material = ml;
                    holeMesh.dispose();
                    SPSMesh.position = new BABYLON.Vector3.Zero();
                    SPS.initParticles = function () {
                        for (var h = 0; h < pointsData.length; h++) {
                            var holePosn = pointsData[h];
                            this.particles[h].position = new BABYLON.Vector3(holePosn.X / 1000, -thickness / 2, holePosn.Y / 1000);
                        }
                    }

                    SPS.initParticles();
                    SPS.setParticles();

                    SPSMesh.parent = parent;

}

Share this post


Link to post
Share on other sites

Thank you Deltakosh for the quick response. I will do a detailed review soon to identify the bottleneck and feedback.

My first review makes me believe that as long as i am interacting with the same canvas, it is unlikely to be of much help. At present, I am investigating if I can do the heavy lifting in another scene and then clone/serialise the mesh and transfer to my main scene. I hope I will be successful.

 

Regards,

Balu

Share this post


Link to post
Share on other sites

Can you do the heavy lifting on another thread via a webworker and then get back the vertices array back into the main thread?
Obviously there WILL be a stop-of-the-world pause when you add the whole shebang to the active Scene though..

Share this post


Link to post
Share on other sites
3 hours ago, adam said:

Could you draw the holes to a texture rather than messing with the geometry?

That was my first approach. My application is for an engineering design and I need to show the holes as visible through a partial transparency of a plate. Texture doesn't give me that effect. With a cylinder placed as a solid mesh + varying colours and the panel with semi transparency gives me the right effect I need. 

Share this post


Link to post
Share on other sites
1 hour ago, adam said:

By any chance was it an issue with the z-ordering of transparent particles?

I haven't checked specifically, but it is unlikely. The trouble is there even when I create just the SPS without any transparency. Actually, the non responsiveness is there whenever I create something that requires reference to the scene (SPS, simple mesh etc) in a large loop. I guess this is a single thread limitation. I assume scene somehow references the canvas and hence cannot be in a web worker. (Not sure though)

Share this post


Link to post
Share on other sites

mmmmh... building a SPS can take some (little) time but this should always be faster than the data download from an ajax request ... simply because the CPU is way much faster than the network anyway.

Did you measure where was your slowing down ? the time between the user click (or other user trigger event) and the end of the download or the time between the start of the download callback function and the end of the SPS construction ?

Share this post


Link to post
Share on other sites
4 hours ago, adam said:

The reason I asked my previous question is because I don't understand why drawing holes in a texture didn't work for you.

Oh. Sorry. Misunderstood your query. I have a number of perforated plates. Upon certain user action, I need to show the holes as "see through" the plates. (Something similar to the image attached. Unfortunately, posting actual image has some legal issues). These holes are currently straight, but could end up weird shaped later. The shape and positions are all calculated using some complex external algorithms. I have been successful in getting the effect by treating the holes as cilners (extrusions in more complex cases) and then using transparency on the outer plate. Drawing only circles at both end does not show the internal path.

The solution has been treating me well except that in the case of generating very large number of holes, user interaction is kind of stuck. (Such as user walking around or choosing other options from a dropdown). I just moved the canvas to an iframe to separate BJS processing from the main page, but alas the main page as well becomes stuck when the hole processing is ongoing. I might be doing something else wrong.

image.thumb.png.3c46e99cee7f473f70b645fdae9e2661.png

Share this post


Link to post
Share on other sites
46 minutes ago, jerome said:

mmmmh... building a SPS can take some (little) time but this should always be faster than the data download from an ajax request ... simply because the CPU is way much faster than the network anyway.

Did you measure where was your slowing down ? the time between the user click (or other user trigger event) and the end of the download or the time between the start of the download callback function and the end of the SPS construction ?

I timed the activity. Each set of holes varies from 200 to 1800 and totaling around 40,000 holes. (20-25 ajax requests). It takes between 20ms to 2200ms. As such, I do not think it is slow even including the ajax timing. If it appears with a delay, it is still acceptable as the user will continue to navigate the scene and do other things while waiting for the shapes appear. The problem I am trying to solve is that when the SPS creation is ongoing, camera/mouse movements in the scene gets stuck and stutters.

Share this post


Link to post
Share on other sites

Maybe "partition" the scene then, so that every new group requested by user is added to a new SPS? 
Again, I don't quite understand at what stage the delay happens: xhr request or scene update? Does it get worse as more items are added?

Share this post


Link to post
Share on other sites
6 minutes ago, max123 said:

Maybe "partition" the scene then, so that every new group requested by user is added to a new SPS? 
Again, I don't quite understand at what stage the delay happens: xhr request or scene update? Does it get worse as more items are added?

Hi max123,

The SPS is already grouped and a new SPS is created in every loop. The code sample I gave was a single cycle. May be I was not very clear on my original query. The query was not about the time taken or delay in processing. The query was about "if the canvas can remain interactive" while the processing is going on.

Imagine you are walking around a room in FPS mode and you click on a wall. The click triggers a lot of activity behind the scene which brings these holes on the wall. While all these are happening in its own time, the person continues to walk around the room and click on more walls. At present, as soon as the event is triggered and the mesh addition starts, the walking around STOPs. The speed is quite fast. But due to the fact that there are so many elements to be added, it is going to take a long time and I am trying to prevent this from freezing the canvas.

I tried using an iframe - which didnt work and now working on creating a second scene to see if i can process it there in a separate iframe and then transfer over the results to the main one. :)

Share this post


Link to post
Share on other sites
6 hours ago, adam said:

It sounds like you need to create all or a lot of your cylinders ahead of time and only show them if you need to.  You should try to avoid the creation of new SPS's if at all possible.

Thank you Adam. I am trying a few different methods and will post back with any luck I have.

Share this post


Link to post
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...

  • Recently Browsing   0 members

    No registered users viewing this page.