Forum

Avoid hiccups when executing other functions

22 October 2015 13:10 #4534
Hi great b4w programmers… I started using your sdk a few months ago and I'm loving it!
I'm building a thesis app-project where I have to update a bunch of data each second and update GUI based on read values. Currently I'm doing this putting my function insite a setTimeout(fn({…}), 1000) but when navigating my 3D scene it has a big hiccup each second. I noticed that when I switched from a 3.5GHz processor to a 1.8GHz one the hiccups lasts longer so I think it's a CPU bottleneck (the GPU is a NVIDIA Quadro K2200 so it should not be the problem).
Into my function I'm contstructing a big array of ~8x14x400 objects and using some of those values to update the scene. I don't know if there is a better way to get rid of these hiccups… do you know any?
Thanks for B4W, it's really awesome and you absolutely need more fame!
22 October 2015 15:08 #4542
Hi great b4w programmers… I started using your sdk a few months ago and I'm loving it!
Hi, salmar_dev, thanks for your praises!


Into my function I'm contstructing a big array of ~8x14x400 objects and using some of those values to update the scene.
This could be the cause of freezes if you call it regularly. Could you paste this function here, so we can understand what actually happens.
Blend4Web Team
23 October 2015 10:38 #4546
if (__mouse_pressed)
    return;
console.info("Updating...");
$http(load_values)
    .then(function (response) {
        var data = null;
        try {
            data = new DataView(response.data);
        } catch (e) {
            console.error(e);
            return;
        }
        tower = floor = measure = 0;
        for (var i = 0; i < ntowers * nfloors * nmeasures; i++) {
            tower = Math.floor(i / (nfloors * nmeasures));
            floor = Math.floor((i / (nmeasures)) % nfloors);
            measure = i % nmeasures;
            var measuretype = measures[measure].type;
            var valueIndex = 12 + measure * 9 + ( floor * nmeasures * 9) + (tower * nfloors * nmeasures *9 );
            var valueStatus = valueIndex + 8;
            towers_measures[tower][floor][measure].value = data.getFloat64(valueIndex, true);
            towers_measures[tower][floor][measure].status = data.getUint8(valueStatus, true) & 1;
            towers_measures[tower][floor][measure].used = (data.getUint8(valueStatus, true) & 128) ? 1 : 0;
        }
        for ( var i = 1; i < ntowers; i++ ) {
            var floor_switches_bits = towers_measures[i][0][pcs_switches_index].value;
            var floor_alarms_bits = towers_measures[i][0][pcs_alarm_index].value;
            var switches_status = [];
            var alarms_status = [];
            floor_switches_bits = floor_switches_bits >>> 2;
            floor_alarms_bits = floor_alarms_bits >>> 2;
            if ( floor_switches_bits != 0 )
                tower_control.set_tower_status(i, 1);
            else
                tower_control.set_tower_status(i, 0);
            for (var j = 0; j < 14; j++) {
                switches_status[j] = floor_switches_bits & 1;
                alarms_status[j] = floor_alarms_bits & 1;
                floor_switches_bits = floor_switches_bits >>> 1;
                floor_alarms_bits = floor_alarms_bits >>> 1;
                if(switches_status[j] && alarms_status[j])
                    tower_control.set_FCM_status(i, j+1, "ON_ALARM");
                else if(switches_status[j])
                    tower_control.set_FCM_status(i, j+1, "ON");
                else if(alarms_status[j])
                    tower_control.set_FCM_status(i, j+1, "OFF_ALARM");
                else
                    tower_control.set_FCM_status(i, j+1, "OFF");
            }
        }
        $localStorage.tower_values = JSON.stringify(towers_measures);
    }, function (error) {
        // todo handle errors
    });
}

Inside set_FCM_status I use set_nodemat_value and set_nodemat_rgb on few items (8x15)
I'm using AngularJS (call $http with some params) and HTML5 local storage to share this big array of data between browser's tabs.
To avoid hiccups so far I've avoided the update when the user pans the scene but even if the camera moves I have hiccups.
23 October 2015 17:51 #4552
I can't say definitely where is the problem. There is a plenty of possible reasons which cause the lags.
I'm not familiar with AngularJS but another framework - jQuery Mobile which we use in our "Viewer" application has some bottlenecks. So it can be slow in a certain cases.
JSON.stringify() function can also be the cause of troubles here if the "towers_measures" object is too big. The best way to figure this out is to use profiling tools.
You can use "Profiles->Collect Javascript CPU Profile" in the Chrome console during the camera moving and then see which function takes a big amount of time.


Into my function I'm contstructing a big array of ~8x14x400 objects
Also it isn't a good approach to construct a big new array in a function which is called many times. It's better to use previously created array and just rewrite it every time.
Blend4Web Team
26 October 2015 15:22 #4577
Hi sorry for late reply. I use Profiling Tools but so far I can't identify the real reason for those lags. I'll investigate more and will search a more efficient way to update my objects. Thank you very much for your support and for b4w!
Really, really, really hope to use it for another project (maybe commercial, who knows? )
26 October 2015 17:34 #4584
I use Profiling Tools but so far I can't identify the real reason for those lags.
Chrome allows to save the collected data. We can look at it if you'll attach the profile to the post.
Blend4Web Team
06 November 2015 12:09 #4825
Hi, after some CPU profiling analysis I found that my main problem could be the high number of objects that I have loaded in my scene.
I have about 1063 objects that are selectable and with outlining on hover enabled. Static objects (~131) are placed dinamically and have LODs objects and Force Dynamic Objects enabled (to move them dinamically).
These objects are loaded through multiple data.load calls. I tried to load just one object and then duplicating it but the duplication worked only for the parent, not the children. I didn't find another way to load all these objects in an efficient way.
ps. sorry for late reply
06 November 2015 14:59 #4828
Hi!

These objects are loaded through multiple data.load calls.
Which certain moment the dynamic loading is happened? It's a heavy operation and should be used for loading different levels of a game/scene and other similar tasks.

I tried to load just one object and then duplicating it but the duplication worked only for the parent, not the children. I didn't find another way to load all these objects in an efficient way.
Yes, copying of an object doesn't currently consider parenting and other relations. But instead of dynamic loading you can copy all the needed objects and apply one of the constraint to emulate parenting, e.g. append_stiff(). It should be much faster.

I have about 1063 objects that are selectable and with outlining on hover enabled.
Outlining on hover means that the mouse move action will cause an iterating through all scene objects. But if the hiccups appear only when the camera moves (and not just the mouse) then the problem isn't here.

I found that my main problem could be the high number of objects that I have loaded in my scene.
I have about 1063 objects that are selectable and with outlining on hover enabled. Static objects (~131) are placed dinamically and have LODs objects and Force Dynamic Objects enabled (to move them dinamically).
Technically, all your objects are dynamic because of these settings.
On the one hand it isn't good to have too many dynamic objects, because it leads to many draw calls and drops FPS. But on the other hand it's easy to perform frustum culling optimization for them. So it's a kind of a balance. Anyway, moving the camera shouldn't affect FPS by this reason.
Blend4Web Team
06 November 2015 17:59 #4829

These objects are loaded through multiple data.load calls.

Which certain moment the dynamic loading is happened? It's a heavy operation and should be used for loading different levels of a game/scene and other similar tasks
I load all the objects at startup as it's a single scene with all objects rendered.

Yes, copying of an object doesn't currently consider parenting and other relations. But instead of dynamic loading you can copy all the needed objects and apply one of the constraint to emulate parenting, e.g. append_stiff(). It should be much faster.
Ok I could try this but in js code I'm cycling through all children of a given object to update them eventually, so I'm using 'objects.get_parent'. Using 'append_stiff()' I think I'll loose this kind of structure, right? Moreover this structure allows me to have multiple objects with the same name which I use in js code to do a lot of things (identifying the object selected for example)

This is my entire scene:


And this is a close view of a tower:
06 November 2015 18:36 #4830
I load all the objects at startup as it's a single scene with all objects rendered.
OK, it seems normal. At first I thought that it happens suddenly during the application work.

Ok I could try this but in js code I'm cycling through all children of a given object to update them eventually, so I'm using 'objects.get_parent'. Using 'append_stiff()' I think I'll loose this kind of structure, right? Moreover this structure allows me to have multiple objects with the same name which I use in js code to do a lot of things (identifying the object selected for example)
Yes, you're right, 'objects.get_parent' won't work after this. Now, I see that you have a complex structure, therefore copying I think is not an option.

Can you attach the profiling data? It'll help us to identify there is the bottleneck place. And we'll try to think up a workaround or a possible optimization.
Blend4Web Team
 
Please register or log in to leave a reply.