I have animation that happens on dragmove.
However I don't want to waste cycles doing more calculations than I have to.
Essentially I want the dragmove events to only redraw at a reasonable animation rate.
In other words dragmove events come in as fast as they can however I only want to execute code as often as needed for smoothness for user.
So far the only solution I have come up with is to have a separate animation loop that does the redraw and ondragmove just sets the variables I need. Is there a more elegant way of doing this?
Think about it this way. The 30 FPS is your limitation. The events will go on their own time regardless your limitations.
So your idea is not that "un-elegant". I would say, it's the only way to go.
When ever you get a motion event, store it locally, if you already have it stored, override the old data(This is the ignoring part). From your 30 FPS loop, sample the motion event, if you got anything, than execute and destroy it.
This is about it. Pretty much your own words.
Related
Link 1 - http://horebmultimedia.com/Sam3/
Link 2 - http://horebmultimedia.com/Sam5/
In the above links, i have added a set of numbers added in separate containers in each file and u can find the FPS on the top right. The issue is when i mouse over in this Link 1 and click any numbers, as u see the FPS is getting slower & slower, making the world to rotate slower on the left side.
While on this link, Link 2, I added only one mouse over and 5 mouse over, but there is not much difference in FPS, why it lags so much when i have 37 containers. I can give my code if u need to resolve.
I had a rough look at your code, but digging through an entire project is not a fantastic way to debug an optimization problem.
The first thing to consider is if you have mouseOver enabled on your stage, I would recommend a liberal use of mouseChildren=false on interactive elements, and mouseEnabled=mouseChildren=false on anything not interactive. The rollover could be a big cause, as it requires everything to be drawn 20 times per second (in your usage). Text and vectors can be expensive to redraw.
// Non-interactive elements (block all mouse interactions)
element.mouseEnabled = element.mouseChildren = false;
// Interactive elements (reduce mouse-checking children individually)
element.mouseChildren = false;
If they don't change, you might consider caching text elements, or button graphics. I think I saw some caching in the source - but its generally a good thing to consider.
--
With that said, debugging optimization can be tough.. If removing all the buttons brings your performance up, consider how your buttons are being constructed, and what their cost is.
* Mouse over is expensive
* Vectors and text can be expensive
* Caching can help when used right, but can be expensive if it happens too often.
* Review what is happening on tick(). Sometimes, code is running constantly, which doesn't need to.
--
A few other notes:
This does not do what you think: _oButton.off("mousedown"); -- You need to pass the result of the on() call. If you are just cleaning up, call _oButton.removeAllEventListeners().
You don't need to set the cursor on mouseover. The cursor will only change when it rolls over -- so just set it once, and then get rid of your buttonover stuff.
It might make sense to just extend EventDispatcher for your custom classes, which gives you things like the on() method, which supports a data param. I might recommend this in place of your addEventListener stuff in CTextButton
Note that RAF does not support a framerate property (it just uses the browser's RAF rate, which is usually 60fps). Use createjs.Ticker.timingMode instead of the deprecated useRAF.
Hope that helps a little.
I noticed that the data I'm getting from the leap motion controller is quite noisy. Apart from the obvious (i.e. position of the fingers), I've encoutered events such as
fingers moving between hands,
"phantom" hands appearing,
fingers disappearing and reappearing immediately afterwards.
Does the API (in particular the Javascript API) provide any means of cleaning this data or is there any other way of making this data less noisy? All of these events can be handled in user code of course, but it seems that having to do this yourself every time would be less than ideal.
In short, no- at the moment the developers have to implement the logic for that. Be aware that this might not be true in the future, the API changes fast.
I had problems with this as well, I solved this by using a circular queue with a max limit of (for example) 100 frames. Then I would track the data for just one pointable. I would then filter the data for the conditions I considered to be not normal. For example width, which is very unreliable. I would get the modal value, and accept a +2 -2 range for the modal value. I would ignore everything else. Works rather well :)
In short, as you already mentioned, you need to collect data, and filter out the noise. Tool and width precision will change they told me. Do a search on the forum for isTool and see how others found ways to get 'stabilized' data.
For me the solution was (for what I wanted, which was to track one pointable, and a reliable width):
Hold a queue of max X items
Set a tolerance limit
Compare the data in the queue
Filter out what was considered noise
In my game engine, there are objects that need to be updated periodically. For example, a scene can be lowering its alpha, so I set an interval that does it. Also, the camera sometimes needs to jiggle a bit, which requires interpolation on the rotation property.
I see that there are two ways of dealing with these problems:
Have an update() method that calls all other object's update methods. The objects track time since they were last updated and act accordingly.
Do a setInterval for each object's update method.
What is the best solution, and why?
setInterval does not keep to a clock, it just sequences events as they come in. Browsers tend to keep at least some minor amount of time between events. So if you have 10 events that all need to fire after 100ms you'll likely see the last event fire well into the 200ms. (This is easy enough to test).
Having only one event (and calling update on all objects) is in this sense better than having each object set it's own interval. There may be other considerations though but for at least this reason option 2 is unfeasible.
Here is some more about setInterval How do browsers determine what time setInterval should use?
The best way I have found out to make a good update() function and keeping a good framerate and less load is as following.
Have a single update() method which draws your frame, by looping some sort of queue/schedule of all drawable object his own update() function which are added to this update event queue/ schedule. (eventlistener)
This way you don't have to loop all objects which are not scheduled for a redraw/update (like menu buttons or crosshairs). And you don't have an over abundance of intervals running for all drawable objects.
I recommend using the update() method over the setInterval.
Also, I would guess that the timing on the several setintervals running would be unreliable.
Another possibility, depending on what other things are happening in your game, using a bunch of separate intervals could introduce race conditions in the counting and comparing of scoring, etc
The proposed algorithms proposed are not exclusive to the related method. That is, you can use setInteval to call all the update methods, or you can have each object update itself by repeatedly calling setTimeout.
More to the point is that a single timer is less overhead than multiple timers (of either type). This really matters when you have lots of timers. On the other hand, only one timer may not suit because some objects might need to be updated more frequently than others, or to a different schedule, so just try to minimise them.
An advantage with setTimeout is that the interval to the next call can be adjusted to meet specific scheduling requirements, e.g. if one is delayed you can skip the next one or make it sooner. setInterval will slowly drift relative to a consistent clock and one–of adjustments are more difficult.
On the other hand, setInteval only needs to be called once so you don't have to keep calling the timer. You may end up with a combination.
Currently, I am rendering WebGL content using requestAnimationFrame which runs at (ideally) 60 FPS. I'm also concurrently scheduling an "update" process, which handles AI, physics, and so on using setTimeout. I use the latter because I only really need to update objects roughly 30 times per second, and it's not really part of the draw sequence; it seemed like a good idea to save the remaining CPU for actual render passes, since most of my animations are fairly hardware intensive.
My question is one of best practices. setTimeout and setInterval are not particularly kind to battery life and CPU consumption, especially when the browser is not in focus. On the other hand, using requestAnimationFrame (or tying the updates directly into the existing render phase) will potentially enforce far more updates every second than are strictly necessary, and may stop updating altogether when the browser is not in focus or at other times the browser deems unnecessary for "animation".
What is the best course of action for updating, but not rendering content?
setTimeout and setInterval are not particularly kind to battery life and CPU consumption
Let's be honest: Neither is requestAnimationFrame. The difference is that RAF automatically turns off when you leave the tab. That behavior can be emulated with setTimeout if you use the Page Visibility API, though, so in reality the power consumption problems between the two are about on par if used intelligently.
Beyond that, though, setTimeout\Interval is perfectly appropriate for use in your case. The only thing that you may want to be aware of is that you'll be hard pressed to get it perfectly in sync with the render loop. You'll have cases where you may draw one too many times before your animation update hits, which can lead to minor stuttering. If you're rendering at 60hz and updating at 30hz it shouldn't be a big issue, but you'll want to be aware of it.
If staying perfectly in sync with the render loop is important to you, you could simply have a if(framecount % 2) { updateLogic(); } at the top of your RAF callback, which effectively limits your updates to 30hz (every other frame) and it's always in sync with the draw.
I've got some borders that animate around thumbnails in on mouseenter and out on mouseleave. Say a user moves their mouse between two repeatedly, quickly enough that the animation doesn't have time to finish between before the user moves on. The result is that, even if the mouse isn't moving, the border bounces back and forth between the two images they switched between until all the queued animations finish, which can take a while. To prevent this, I've added a .dequeue() before the .animate(). This works well, except that I may have some other animations running. I don't want to stop/dequeue these.
Is there a way to selectively dequeue animations, excluding some? The ones I want to exclude are scroll animations, also triggered on mouseenter.
Are you looking for something like this?
EDIT:
Ah I see, here is the closest solution that i can think of.
There's no built-in way to do this, I don't think you'll find an approach that doesn't involve re-writing a fair portion of the animation engine. The animations take an object when queued. It loops though all properties in the object and determines the start value and end value. To get the value at the step of the animation (depending on your easing, we'll use linear as an example here), it multiplies that difference by the percentage along the animation is.
It's all handled as a group of properties, you can't really split them off and stop the animation of some and not others...it just isn't built to be handled that way. If it were, it's be a huge performance penalty to handle them separately (think about how many times this code runs)...so for such a rare case (your needs here), the library is going to choose the high-performance route that fits the other 99% of cases.