Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not redraw continuous #2

Open
Dandandan opened this issue Dec 7, 2009 · 11 comments
Open

Do not redraw continuous #2

Dandandan opened this issue Dec 7, 2009 · 11 comments

Comments

@Dandandan
Copy link

Please redraw only on animation using noLoop() and own draw calls.

(smaller issue btw, please place frameRate(30) in your setup function instead of draw).

Hope you appreciate my comment.

@michael
Copy link
Owner

michael commented Dec 7, 2009

Hi!
That sounds like a good idea. Could you give a short example where to put the noLoop() calls etc.?

Also I think recalculating all the state-values in update isn't always necessary. It should depend on whether the animation is playing or not. I'm just wondering how I would then detect mouseOver events (when different slices/segments are activated).

frameRate(30) must go to setup(), obviously ;) Thanks!

I'm doing some modifications on donut while preparing the launch of ASKKEN™ 1.0. Saving some cpu cycles on Donut drawing would help a lot there. ;)

@Dandandan
Copy link
Author

noLoop() should go in setup(), then processingjs doesn't call your draw function anymore.
You should redraw only when there are new properties to draw. so i think you have to call your draw (or redraw) function manually with an setInterval on each 1000/frameRate ms and do a clearInterval when the animation is stopped. Just like this (on your tweet example):

import("Tween.lib");

class MovingObject {
float x;
float y;
float tx;
float ty;
Tween t;
Tween t2;

public MovingObject(float x, float y, float tx, float ty) {
this.x = x;
this.y = y;
this.tx = tx;
this.ty = ty;
t = new Tween(this, "x", Tween.strongEaseInOut, x, tx, 2);
t2 = new Tween(this, "y", Tween.bounceEaseInOut, y, ty, 2);
}

public void update() {
t.tick();
t2.tick();
}

public int isPlaying() {
return t.isPlaying();
}

public void draw() {
noStroke();
fill(120);
ellipse(x, y, 30, 30);
}

public void restart() {
t.start();
t2.start();
}
}

MovingObject mo;

void setup() {
size(400, 150);
mo = new MovingObject(50, 30, 360, 130);
noLoop();
frameRate(30);
}

void animate() {
if (!l) {
l = setInterval(
function() {
if (mo.isPlaying()) {
redraw();
}
else {
clearInterval(l);
l = 0;
}
}, 1000/frameRate
);
}
}

void draw() {
background(244);
mo.update();
mo.draw();
}

void mousePressed() {
mo.restart();
animate();
}

oh and these lines in your draw function:
" stroke(0);
fill(0);

pushMatrix();
popMatrix();" seem to do nothing.

I really like the design of ASKKEN! It is really a nice way to browse for information. Looking forward to ASKKEN™ 1.0 ;)

@Dandandan
Copy link
Author

@michael
Copy link
Owner

michael commented Dec 7, 2009

Thank you! Great ideas!

I'll try to apply this approach to the current ASKKEN implementation and merge it back to DONUT when it's ready. However regarding ASKKEN, things seem to be a bit more difficult. The main reason why I'm redrawing all the time is, that nodes and edges in ASKKEN are organized by a particle system. That means nodes are likely to move around all the time (at least slowly to find their right place) which requires a redraw every iteration. Do you have an idea how I could come around that?
I mean at least I can save performance when I skip update() (except for the x/y position update resulting from the particle system) if no animation is playing. However.. I'm not sure if I can save some draw iterations here. Any ideas?

Thank you so far :)

@Dandandan
Copy link
Author

Ehm, yeah that's more difficult. Maybe some options:

  1. You could check (if you don't use floats for your rendering) wether or not the positions did change and only draw things if they did. So you don't do a noLoop but don't draw (and background fill) all the time.
  2. Stop the particle system temporarily if there is nearly no change anymore.
  3. Use animations for most things (like adding a donut) and only use physics when you drag around the donuts and then do (2).
  4. Use animations and come up with an other design.

"I mean at least I can save performance when I skip update() (except for the x/y position update resulting from the particle system) if no animation is playing. However.. I'm not sure if I can save some draw iterations here"

For the update thing I think you could use the same technique as described above, but then calling the update function. I don't know if it improves performance much because on update() it doesn't draw things, does it?

Good luck :)

@Dandandan
Copy link
Author

By the way, to me seems option 3 the most plausible option + you could accelerate the process of stabilizing the donuts.

@michael
Copy link
Owner

michael commented Dec 7, 2009

Aii. Good thinking. I'll take that into consideration. Now I need some "particlesystemStableEnough?" detection, to turn it off when not needed. ;)

What is your background Dan? Are you coming from the (native) Processing community?
Really great to get some input, since I'm quite new to the computer graphics business. I started off with Processing.js, so there's no Processing past in my case. ;)

Do you have some sketches/examples online? In case you have, pls share them. :)

@michael
Copy link
Owner

michael commented Dec 7, 2009

Regarding update().... DONUT's update calculations are quite heavy. So that might be the cause for some frame drops -> needs to be tested.
Mhh... maybe a profiling tool could reveal that. Don't know any. :/

@Dandandan
Copy link
Author

I am just a first year (so a couple of months) computer science student. I did some time ago experiments with processingjs just as an ebook (http://speechcorpus.googlepages.com/ebook.html) and a very simple window manager. Coming days I have probably no time to investigate further, maybe Thursday or weekend.

Firebug (great tool!, can profile under console tab and then click profile and after a while again) reveals this:

(donutsegment.draw()) 2435 16.8% 1937.867ms 7951.808ms 3.266ms 1.02ms 42.639ms 1 (line 225)

(donutslice.draw()) 16558 15.83% 1826.078ms 4102.711ms 0.248ms 0.139ms 24.474ms 1 (line 92)

arc 5222 12.16% 1403.095ms 1403.095ms 0.269ms 0.062ms 9.856ms processing.js (line 1628)

array.size() 496350 8.26% 952.607ms 952.607ms 0.002ms 0.001ms 0.074ms processing.js (line 507)

Donut.totalSlices() 29220 6.96% 802.435ms 1417.268ms 0.049ms 0.045ms 0.13ms 1 (line 379)

stroke 22268 6.78% 781.988ms 1389.776ms 0.062ms 0.028ms 10.156ms

line 16558 5.2% 600.285ms 600.285ms 0.036ms 0.023ms 8.199ms processing.js (line 1649)

color 30996 4.82% 556.414ms 720.088ms 0.023ms 0ms
8.211ms processing.js (line 534)
fill 7235 2.06% 237.992ms 345.499ms 0.048ms 0.029ms 3.498ms

According to Firebug the update function is this:
Donut.update() 487 0.53% 61.524ms 2460.399ms 5.052ms 4.707ms 6.802ms

(I've added the correct names, don't know why but Firebug was reporting array.clear instead of array.size).

You could iterate faster (if you didn't know) over an array by the way by storing the length(s) of (an) array(s) before the for loop(s). That can help a little bit.

@Dandandan
Copy link
Author

Oh and one big deal: I think yo can remove those lines of Donutsegment.draw
" fill(DONUT_BACKGROUND);

noStroke();

strokeWeight(this.breadth+2*OUTER_BORDER);

stroke(DONUT_BACKGROUND);

noFill();

arc(donut.x, donut.y, (donut.radius)*2, (donut.radius)*2, this.angleStart, this.angleStop);"

does nothing :)

@Dandandan
Copy link
Author

found some time:
http://pastebin.org/62191
totalslizes is just a data member of donut, saves some cycles :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants