"Pulsating" effect...what's the proper method? - Page 2 - WoWInterface
02-06-10, 06:43 AM   #21
nightcracker
A Molten Giant

Join Date: Sep 2009
Posts: 716
 Originally Posted by Hati-EK Code: `last_update = last_update -0.25` is more precise and does not skip seconds (even if this would just be some miliseconds) than reseting the whole value to 0 - (ie last_update could be 0.25182965 - so you would missing 0.00182965 - if you have this ~1000 times there's something missing
Nope, because THIS time if you run at 120 fps then the function would run a lot more then when at 10 fps.
__________________
Three things are certain,
You, victim of one.

02-06-10, 08:08 AM   #22
Hati-EK
A Fallenroot Satyr
Join Date: Jul 2008
Posts: 20
 Originally Posted by nightcracker Nope, because THIS time if you run at 120 fps then the function would run a lot more then when at 10 fps.
this is right - at 120fps the function is more fluently ... as the frequency is another - 1/120 vs. 1/10 - but the sampling frequency is 0.25 - so at 120fps it would take 30frames to match the sampling frequency - with 10fps it would take 2.5frames (3frames as there are NO floating frames)

120 fps:
approx. elapsed = 1/120 = 0.0083333333333333s per OnUpdate ( called frequence g in rest of text )
sampling frequency f = 0.25 Hz (or 4fps = 1/4Hz)
f = 30*g
so every 30-frame((n*30)%120, n<-N{0,1,2,..) the SinusFunction() is called - at this point it works fine

now think of ppl having an average fps of not 120fps - like you said 10fps
drawing frequency h = 1/10 Hz
sampling frequency f = 0.25 Hz
resulting that point of collide = frame2.5, as there is no frame 2.5, it will take frame 3 (>=)
time between frame2.5 and frame3 is t=((frame3-frame2)/2);
frame2 is drawn after 0.2s, frame3 after second 0.3 (on time graph) - would result in a 0.05s delay

so with last_update=0, it will result in:
frame1 drawn - frame2 drawn - frame3 drawn - function fires, last_update is now 0 again - frame4 drawn - frame5 drawn (NOW it should fire again - but it doesn't as this is again 0.2 not 0.25) - frame6 drawn - function fires and again 3 frames required

with last_update=last_update-sampling_frequency:
frame1 drawn - frame2 drawn - frame3 drawn - function fires, last_update now is 0.05 - frame4 drawn (last_update 0.15) - frame5 drawn(last_update 0.25) - function fires correctly at (50% of fps as it should with sampling frequency 0.25 - and not at 60%) - frame 6 drawn - etc...

and ppl have not an average fps of continuously 120fps (atleast not the most have)

Last edited by Hati-EK : 02-06-10 at 08:19 AM. Reason: replaced 1 s by Hz

02-06-10, 08:30 AM   #23
Torhal
A Pyroguard Emberseer

Join Date: Aug 2008
Posts: 1,196
 Originally Posted by Hati-EK Code: `last_update = last_update -0.25` is more precise and does not skip seconds (even if this would just be some miliseconds) than reseting the whole value to 0 - (ie last_update could be 0.25182965 - so you would missing 0.00182965 - if you have this ~1000 times there's something missing
This is true, if you're looking to be precise.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.

02-06-10, 08:31 AM   #24
nightcracker
A Molten Giant

Join Date: Sep 2009
Posts: 716
 Originally Posted by Hati-EK this is right - at 120fps the function is more fluently ... as the frequency is another - 1/120 vs. 1/10 - but the sampling frequency is 0.25 - so at 120fps it would take 30frames to match the sampling frequency - with 10fps it would take 2.5frames (3frames as there are NO floating frames) 120 fps: approx. elapsed = 1/120 = 0.0083333333333333s per OnUpdate ( called frequence g in rest of text ) sampling frequency f = 0.25 Hz (or 4fps = 1/4Hz) f = 30*g so every 30-frame((n*30)%120, n<-N{0,1,2,..) the SinusFunction() is called - at this point it works fine now think of ppl having an average fps of not 120fps - like you said 10fps drawing frequency h = 1/10 Hz sampling frequency f = 0.25 Hz resulting that point of collide = frame2.5, as there is no frame 2.5, it will take frame 3 (>=) time between frame2.5 and frame3 is t=((frame3-frame2)/2); frame2 is drawn after 0.2s, frame3 after second 0.3 (on time graph) - would result in a 0.05s delay so with last_update=0, it will result in: frame1 drawn - frame2 drawn - frame3 drawn - function fires, last_update is now 0 again - frame4 drawn - frame5 drawn (NOW it should fire again - but it doesn't as this is again 0.2 not 0.25) - frame6 drawn - function fires and again 3 frames required with last_update=last_update-sampling_frequency: frame1 drawn - frame2 drawn - frame3 drawn - function fires, last_update now is 0.05 - frame4 drawn (last_update 0.15) - frame5 drawn(last_update 0.25) - function fires correctly at (50% of fps as it should with sampling frequency 0.25 - and not at 60%) - frame 6 drawn - etc... and ppl have not an average fps of continuously 120fps (atleast not the most have)
What I say now I assuming you meant this:

Code:
```do
local last_update = 0
local updater = CreateFrame("Frame", nil, UIParent)

updater:Hide()
updater:SetScript("OnUpdate",
function(self, elapsed)
last_update = last_update + .25

if last_update <= -.25 then
RunSinFunction()
last_update = 0
end
end)
end```
Then that is equal to this:
Code:
```do
local start = 0
local updater = CreateFrame("Frame", nil, UIParent)

updater:Hide()
updater:SetScript("OnUpdate", function(self, elapsed)
start = start + .25
SomeFrame:SetAlpha(math.sin(start))
end)
end```
Which means that the speed of the pulsing is determined by your FPS, not the amount of fluentness(is that a word?).
__________________
Three things are certain,
You, victim of one.

Last edited by nightcracker : 02-06-10 at 08:42 AM.

02-06-10, 08:41 AM   #25
Hati-EK
A Fallenroot Satyr
Join Date: Jul 2008
Posts: 20
 Originally Posted by nightcracker What I say now I assuming you meant this: Code: ```do local last_update = 0 local updater = CreateFrame("Frame", nil, UIParent) updater:Hide() updater:SetScript("OnUpdate", function(self, elapsed) last_update = last_update + .25 if last_update <= -.25 then RunSinFunction() last_update = 0 end end) end``` Then that is equal to this: Code: ```do local start = 0 local updater = CreateFrame("Frame", nil, UIParent) updater:Hide() updater:SetScript("OnUpdate", function(self, elapsed) start = start + .25 SomeFrame:SetAlpha(math.sin(start)) end) end``` Which means that the speed of the pulsing is determined by your FPS, not the amount of fluentness(is that a word?).

nah
i meant this :
Code:
```do
local last_update = 0
local updater = CreateFrame("Frame", nil, UIParent)

updater:Hide()
updater:SetScript("OnUpdate",
function(self, elapsed)
last_update = last_update + elapsed

if last_update >= 0.25 then
RunSinFunction()
last_update = last_update-0.25
end
end)
end```

 Originally Posted by Torhal This is true, if you're looking to be precise.
well it's a sinus function - where little differences may cause weird results or atleast not nice looking ones

Last edited by Hati-EK : 02-06-10 at 08:44 AM.

02-06-10, 08:42 AM   #26
nightcracker
A Molten Giant

Join Date: Sep 2009
Posts: 716
Oh I see... That's pretty amazing :P

I still think though that using sin every quarter of a second isn't NEARLY as efficient then multiplying by -1. And I see the disadvantage of my function, it uses SetAlpha WAAAAAAAAAY too often. This should be much much more efficient.

Code:
```frame.mult = 1
frame.alpha = 1
frame.tslu = 0 -- time since last update
frame:SetScript("OnUpdate", function(self, elapsed)
self.tslu = self.tslu + elapsed
if self.tslu > .25 then
self.tslu = 0
self:SetAlpha(self.alpha)
end
self.alpha = self.alpha - elapsed*self.mult
if self.alpha < 0 and self.mult > 0 then
self.mult = self.mult*-1
self.alpha = 0
elseif self.alpha > 1 and self.mult < 0 then
self.mult = self.mult*-1
end
end)```
Final question, is it efficienter to use solution #1 or #2? I can hardly imagine that mod is faster then setting a variable to a table, but I may be wrong since frames have metatables etc etc etc...

#1
Code:
```self.tslu = self.tslu + elapsed
if self.tslu > .25 then
self.tslu = 0
self:SetAlpha(self.alpha)
end```
#2
Code:
```self.tslu = self.tslu + elapsed
if self.tslu%.25 < .125 then
self:SetAlpha(self.alpha)
end```
__________________
Three things are certain,
You, victim of one.

02-06-10, 08:53 AM   #27
Hati-EK
A Fallenroot Satyr
Join Date: Jul 2008
Posts: 20
 Originally Posted by nightcracker Final question, is it efficienter to use solution #1 or #2? I can hardly imagine that mod is faster then setting a variable to a table, but I may be wrong since frames have metatables etc etc etc... #1 Code: ```self.tslu = self.tslu + elapsed if self.tslu > .25 then self.tslu = 0 self:SetAlpha(self.alpha) end``` #2 Code: ```self.tslu = self.tslu + elapsed if self.tslu%.25 < .125 then self:SetAlpha(self.alpha) end```
well to #2:
i would say permanently incrementing of a variable may cause an overflow (dunno about max value in lua) - as you aren't calc the modulo and store it

Code:
```self.tslu = (self.tslu + elapsed)%.25
if self.tslu <= elapsed then
self:SetAlpha(self.alpha)
end```
might be better

Last edited by Hati-EK : 02-06-10 at 08:57 AM. Reason: fix init run

02-12-10, 06:57 AM   #28
zork
A Pyroguard Emberseer

Join Date: Jul 2008
Posts: 1,739
If I hadn't stopped playing atm I would post you an example with the animation system.

Using onUpdates to do this is out of date.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW) | TDMOG

 "I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

02-12-10, 10:52 AM   #29
Slakah
A Molten Giant

Join Date: Aug 2007
Posts: 863
 Originally Posted by zork If I hadn't stopped playing atm I would post you an example with the animation system. Using onUpdates to do this is out of date.
Is the animation system more efficient?

02-12-10, 12:24 PM   #30
Haleth
This Space For Rent

Join Date: Sep 2008
Posts: 1,173
Sorry for thread hijack, but how can this code be applied to a single animation instead of a looping 'pulse'? I'm trying to add opening/closing animations to some addon frames, for example in the following code:

Code:
```local function Stuffing_Open()
Stuffing.frame:Show()
end

local function Stuffing_Close()
Stuffing.frame:Hide()
end```
I've tried a couple of things, but no luck.

02-12-10, 12:55 PM   #31
Hati-EK
A Fallenroot Satyr
Join Date: Jul 2008
Posts: 20
 Originally Posted by Haleth Sorry for thread hijack, but how can this code be applied to a single animation instead of a looping 'pulse'? I'm trying to add opening/closing animations to some addon frames, for example in the following code: Code: ```local function Stuffing_Open() Stuffing.frame:Show() end local function Stuffing_Close() Stuffing.frame:Hide() end``` I've tried a couple of things, but no luck.
maybe you are looking for

frame:SetScript('OnShow', doSomethingOnShow)

or frame:SetScript('OnHide', doSomethingOnHide)

?

02-12-10, 01:17 PM   #32
nightcracker
A Molten Giant

Join Date: Sep 2009
Posts: 716
 Originally Posted by Slakah Is the animation system more efficient?
It's not more efficient, the mem/cpu usage does get dumped at the blizzard addons(so it seems more efficient).
__________________
Three things are certain,
You, victim of one.

06-25-10, 08:39 AM   #33
Smacker
A Deviate Faerie Dragon

Join Date: Jul 2009
Posts: 16
Use the built-in animation code:

Code:
```	local alpha = animationGroup:CreateAnimation("Alpha");
alpha:SetOrder(order);
alpha:SetDuration(duration);
alpha:SetMaxFramerate(fps);
alpha:SetChange(alphaTo);```

06-26-10, 02:07 PM   #34
Dawn
A Molten Giant

Join Date: May 2006
Posts: 918
Arrrr, sometimes thread necrotism is good stuff, indeed. I somehow missed this one. *bookmarks thread*
__________________
Rock: "We're sub-standard DPS. Nerf Paper, Scissors are fine."
Paper: "OMG, WTF, Scissors!"
Scissors: "Rock is OP and Paper are QQers. We need PvP buffs."

"neeh the game wont be remembered as the game who made blizz the most money, it will be remembered as the game who had the most QQ'ers that just couldnt quit the game for some reason..."

06-28-10, 01:28 AM   #35
An Aku'mai Servant

Join Date: Nov 2007
Posts: 32
 Originally Posted by nightcracker Oh I see... That's pretty amazing :P I still think though that using sin every quarter of a second isn't NEARLY as efficient then multiplying by -1. And I see the disadvantage of my function, it uses SetAlpha WAAAAAAAAAY too often. This should be much much more efficient.
I may be wrong, but setting the alpha of a frame is not CPU intensive. The graphics engine works hard, whatever the alpha is, whether it has changed or not. Using sine I think would give a more pleasing looking pulse.

07-30-10, 01:21 PM   #36
lieandswell
A Cyclonian

Join Date: Jan 2007
Posts: 45
If you wanted to use the Blizzard animation API in XML, you could do something like:

Code:
```<Frame>
...
<Animations>
<AnimationGroup name="\$parentPulse" parentKey="pulse" looping="BOUNCE">
<Alpha change="-1" duration="1.5"/>
</AnimationGroup>
</Animations>
<Scripts>