WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   The ring theory part two (https://www.wowinterface.com/forums/showthread.php?t=45918)

zork 03-02-13 09:46 AM

The ring theory part two
 
Based on this:
http://www.wowinterface.com/forums/s...ght=discokugel
http://www.wowinterface.com/forums/s...ad.php?t=45817

Today after finishing my config I had some time to think about stuff. What really got me is that no-one has ever used scrollFrames to do stuff. I set up an experiment that I may try to prove if I have time.

I made the following graphics:

Basic ring setup:


We put a scrollFrame with an inline texture into ring segment 1:


This will happen if we change the setpoint of the scrollFrame and the setpoint of the texture inside the scrollFrame:


This is what is going to happen if we only adjust the size of the scrollframe:


What about rotation? Let's see. Hmm the offset does not fit.


So this is what happens if we correct the offset.


What we are doing in the last screenshot. We rotate the scrollFrame right while adjusting the setpoint properly. Additionally we rotate the ringTexture inside the scrollFrame in opposite direction.

*edit*

Ahhh...got an even better idea. Why would you rotate the scrollFrame at all? We can just leave as it is and just rotate the texture inside.

This is what will happen:

The pink thingy is the alpha layer of the ring texture.


Now if we rotate the texture inside the scrollFrame it will adjust on it's own.


This should make it very simple to create any kind of rings. Just set up 4 scrollFrames and throw in any ring texture you want. The number of rings per scrollFrames is unlimited. Each ring texture can be rotated individually.

Only one limitation. Start and end point of a ring segment can only be in one segment if at least one point is at 0° or 90°.

It even should be possible to do full half-rings with only 2 scrollFrames. Your ring texture would span 180° then.

Nibelheim 03-02-13 10:22 AM

Tripped out :)

zork 03-02-13 11:04 AM

Hmm...actually I set down to prove the concept.

It works!



Addon:
http://www.wowinterface.com/download...rTestRing.html

SVN:
http://code.google.com/p/rothui/sour...5.0/rTestRing/

Free your mind.

If I look at how simple that actually is I want back my time when I did rRingThing. Damnit.

Nibelheim 03-02-13 11:29 AM

Quote:

Originally Posted by zork (Post 273818)
Hmm...actually I set down to prove the concept.

If I look at how simple that actually is I want back my time when I did rRingThing. Damnit.

Many a scientist must have thought that throughout history :p

humfras 03-03-13 05:04 AM

This is superb.

There are just some major drawbacks to the texture rotation:
It only works for mono-color and symmetrical textures.
Otherwise, the illusion fails.

Haleth 03-03-13 05:47 AM

Looks great, zork. I love your ideas. Your 'scroll frame revelation' made me laugh :p

It actually inspired me to try and use a scroll frame myself for some to-do list I'm working on. Sliding panel with transparent frames (so no lazy moving behind the parent frame) \o/



The possibilities... they are endless.

Edit: You could also make a pretty cool experience bar with it. A full circle represents one level. You have a segment for the current experience, then a second segment starting at the end of the first one representing rested experience. If you make the second one semi-transparent, you could see how far it overlaps into the next level as well, something which traditional experience bars can't do.

zork 03-03-13 07:18 AM

@Haleth
Nice one.

@humfras

You can cheat alot more if you have to. Atleast it's a huge improvement of what we currently had to do.

The texture can use blending and gradients are possible aswell. Additonally you can use overlays or backgrounds. You can recolor on value change. You can even position another texture (spark) ontop of the ring.

Lua Code:
  1. local function calc_health_spark(self,value)
  2.     local spark = self.health_spark.texture  
  3.     local adjust = 0.009
  4.     value = 1-value+adjust
  5.     local mult = 1
  6.     local radian = math.rad(90) + math.rad(value * (mult*90*self.config.health.segments_used))
  7.     spark:SetPoint("CENTER", spark.radius * math.cos(radian), spark.radius * math.sin(radian))
  8.     spark:SetRotation(radian - spark.shiftradian)  
  9.   end

On that note...I have not tested frame rotation which should be possible via animationgroups. Thus some could try to stack textures on a frame and rotate the full frame inside the scrollFrame.

Another big plus is the ability of AnimationGroups. Sth like Animation > SetSmoothing is just nice to have.

Quote:

Sets the smoothing type for the animation. This setting affects the rate of change in the animation's progress value as it plays.

Signature:

Animation:SetSmoothing("smoothType")

Arguments:

smoothType - Type of smoothing for the animation (string)
  • IN - Initially progressing slowly and accelerating towards the end
  • IN_OUT - Initially progressing slowly and accelerating towards the middle, then slowing down towards the end
  • NONE - Progresses at a constant rate from beginning to end
  • OUT - Initially progressing quickly and slowing towards the end

http://wowprogramming.com/docs/widge...n/SetSmoothing


humfras 03-04-13 02:48 AM

Quote:

Originally Posted by zork (Post 273862)

@humfras

You can cheat alot more if you have to. Atleast it's a huge improvement of what we currently had to do.

The texture can use blending and gradients are possible aswell. Additonally you can use overlays or backgrounds. You can recolor on value change. You can even position another texture (spark) ontop of the ring.

Bzgl. sparks teste ich seit einiger Zeit für CursorCastbar die 3D-Zauberanimation (z.B. Shadowbolt) als zusätzliches Rotationsobjet (siehe auch Poisoner5).
Dynamische Texturen (hier: sich verwindente Doppelstränge) brauchen zur Darstellung eine vorlaufende Sichtgrenze. Sollte ja möglich sein.
Problematisch wird es, wenn dynamische Schattenverläufe nötig sind. Oder ist dies mit Overlay-Texturen möglich ('MaskTexture')?

zork 03-13-13 11:56 AM

Lol...SetRotation has a bug. It does sth to my ring texture.



To get it to work properly I had to use the SQRT trick posted by Saiket here:
http://www.wowinterface.com/forums/s...ad.php?t=36679

My code is:
Lua Code:
  1. -- // DiscoKugel2
  2.   -- // zork - 2013
  3.  
  4.   --get the addon namespace
  5.   local addon, ns = ...
  6.  
  7.   local unpack = unpack
  8.   local _G = _G
  9.   local CF = CreateFrame
  10.   local UIP = UIParent
  11.   local abs = math.abs
  12.   local sin = math.sin
  13.   local pi = math.pi
  14.  
  15.   -----------------------------
  16.   -- FUNCTIONS
  17.   -----------------------------
  18.  
  19.   local f = CF("Frame",nil,UIP)
  20.   f:SetSize(512,512)
  21.   f:SetScale(0.5)
  22.   f.w, f.h = f:GetSize()
  23.   f:SetPoint("CENTER")
  24.  
  25.   local t = f:CreateTexture(nil, "BACKGROUND", nil, -8)
  26.   t:SetTexture("Interface\\AddOns\\rTestRing2\\media\\ring")
  27.   t:SetAllPoints()
  28.   t:SetAlpha(0.2)
  29.  
  30.   local sf1 = CF("ScrollFrame",nil,f)
  31.   sf1:SetSize(f.w/2,f.h)
  32.   sf1:SetPoint("LEFT")
  33.  
  34.   local sc1 = CF("Frame")
  35.   sf1:SetScrollChild(sc1)
  36.   sc1:SetSize(f.w,f.h)
  37.  
  38.   local rt1 = sc1:CreateTexture(nil,"BACKGROUND",nil,-6)
  39.   rt1:SetTexture("Interface\\AddOns\\rTestRing2\\media\\ring_half")
  40.   rt1:SetSize(sqrt(2)*f.w,sqrt(2)*f.h)
  41.   rt1:SetPoint("CENTER")
  42.   rt1:SetVertexColor(1,0,0)
  43.   rt1:SetRotation(math.rad(40)) -- etc
  44.  
  45.   --local ag = rt1:CreateAnimationGroup()
  46.   --local anim = ag:CreateAnimation("Rotation")
  47.   --anim:SetDegrees(90)
  48.   --anim:SetDuration(10)
  49.   --ag:Play()

Maybe it has sth to do with the mysterious 1px I read about. Going to try to snip out 1px of my ring.
Afaik I read sth about it in Iriels ring theory. Thus every texture with a transparent outer edge needs to stay away from the texture edge by atleast 1px. Gonna try that. I think they did that to determine matching background colors or the like.

Loooool. That worked. I stripped the outer pixel and BÄÄÄM.



So when working with Texture:SetRotation() you have to make sure to do these:
  • Texture size has to be in SQRT
  • Texture rotation must be in rad
  • Texture file must not hit the other edge of the image or you will get background color copy behaviour that you may not want.

SDPhantom 03-13-13 12:31 PM

The reason for the first bug you mentioned is just the way WoW decides to render the out of bounds area of a texture's image. It tends to duplicate the last pixel out past the bounds of the image in order to fill the rendering area of the texture. This has nothing to do with texture:SetRotation() and will show up if you use texture:SetTexCoord() with coordinates that extend out of bounds.

The problem in which the SQRT method fixes is that Blizzard chose to have a texture shrink so the corners of an image fit in it at a 45 degree angle whenever texture:SetRotation() is used. If you manually calculate the coordinates of the corners and set the texcoord yourself, this doesn't apply. Although it's probably easier and more efficient to just multiply the intended size of the texture object with SQRT(2) as shown by your code example.

zork 03-13-13 01:40 PM

Thanks for the insight SDPhantom.


I'm on the way of creating an oUF layout from this. I really wanted to do this for a long time. Now I'm finally able to make it work properly.

I'm currently setting up the orb templates in my GFX program. Currently I have two templates in mind that I want to bring to life.

Outer ring templates


It can be combined with an orb in the center.

Thanks to SetPortraitToTexture() [http://wowprogramming.com/docs/api/S...raitToTexture] it is even possible to work with circular icon symbols. It may not seem that the icon is circular but in fact it is.

Lua Code:
  1. local icon = select(3,GetSpellInfo(12880))
  2.   --icon = "Interface\\LFGFrame\\UI-LFR-PORTRAIT"
  3.   local t = helper:CreateTexture(nil,"OVERLAY",nil,-8)
  4.   t:SetTexCoord(0, 1, 0, 1)
  5.   t:SetAllPoints()
  6.   --t:SetTexture(icon)
  7.   SetPortraitToTexture(t,icon)

Result:


So a template-idea can be adding a circular cast icon inside a circular castbar and ring unitframes.

*edit*

I made the code of the stuff above available via SVN:
http://code.google.com/p/rothui/sour...5.0/rTestRing2

10leej 03-13-13 08:36 PM

Love what I'm seeing here :)

zork 03-14-13 06:00 AM

Currently doing some font tests and finishing the template:


Not sure which font I want to use. All fonts are from dafont.com (except Arial)

Hmm have not decided on the border width. 4, 6 or 8.

Top version is with castbar. Bottom is without.



zork 03-14-13 09:07 AM

The second layout I want to do is a revival of my oUF_Orbs mod (http://www.wowinterface.com/download...-oUF_Orbs.html).



The problem is the castbar icon. I think I have to put it somewhere else.


Dridzt 03-14-13 10:23 AM

*swoons* :o

10leej 03-14-13 12:55 PM

Why not have the castbar circle the healthbar which circles the mana bar?

Lombra 03-14-13 07:00 PM

Looks amazing. :D

Talyrius 03-14-13 07:05 PM

The bright colors and round shapes remind me of poké balls from Pokémon.

zork 03-15-13 04:42 AM

You get that those are only examples showing the technique behind the scenes right? I'm just showing options. Everything else is personal preference. Do whatever you want. You have the freedom to do so.

You can use any color. You can do quarter, half, full-rings. You can use any ring-width and so on ...

pelf 03-23-13 11:20 AM

Quote:

Originally Posted by zork (Post 274641)
The problem is the castbar icon. I think I have to put it somewhere else.

Top left has symmetry with the cast time. Have you tried putting it behind the main orb?



That looks kind of okay to me.

zork 03-27-13 08:24 AM

Btw...when you are building your ring segments with non-transparent areas inside your ring the following texture will be enough to display all the rings you will ever need.



You do not have to care about ring-width at all. Clever overlaying and frame-stacking is all you need to create the illusion.

Layer 1: (needs two scrollFrames of same color)


Layer 2:


Layer 3:


Handling ring-width is an annoying topic. If you don't have to fiddle with it just don't.

The last step is another layer ontop containing highlight/border textures. But I remommend to delay that step until the layout is finished. It is tedious to create it if you are still working on your layout and change sizes around all the time.

One thing I still need to check out is the effect of the different BlendModes.

SDPhantom 03-27-13 11:57 AM

Here's a link to a good explanation to how BlendModes work.
http://www.wowpedia.org/AlphaMode

zork 04-15-13 02:07 AM

Just some more links on that topic:

http://en.wikipedia.org/wiki/Circular_motion
http://cnx.org/content/m42177/latest...ol11406/latest
http://www.wowinterface.com/forums/s...ad.php?t=45091

zork 04-17-13 03:26 PM

Working on it if I have time to spare. Currently doing the basic setup.

http://imgur.com/a/s1uAA#0

Currently setting everything up.



The main problem atm is getting the frame stacking right. This included frames for border and highlight effects later on.

Basic setup is done. Including a spark texture.



Each ring can sit on 1-4 ring segments.
A segement can handle rings for castbar, health and power.
Each ring can have its own radius.
Each ring consists of a background, ring and a spark texture.

Code will be released under oUF_Donut.

pelf 04-19-13 10:02 PM

What did you decide for where to indicate the spell for a castbar ring?

Resike 04-21-13 06:14 PM

Quote:

Originally Posted by zork (Post 274595)
Lol...SetRotation has a bug. It does sth to my ring texture.



This bug occours, when you call the SetRotation function on a texure which doesn't have enough transparent "spaceborder" to do the full rotate, based on your pivot point. I also run into the problem:



I made a fix like that:

Code:

local ULx, ULy, LLx, LLy, URx, URy, LRx, LRy = texture:GetTexCoord();
local x = (sqrt(2) - 1) / 2
texture:SetTexCoord(ULx + x, ULy + x, LLx + x, LLy - x, URx - x, URy + x, LRx - x, LRy - x);

And its gone:


zork 04-23-13 01:35 AM

SDPanthom wrote an explanation on that here aswell: http://www.wowinterface.com/forums/s...7&postcount=10

Regarding your fix. Does the function only has to be called once per texture prior to any SetRotation calls?

If you have to call it after every SetRotation you will be screwed. What if you rotate the texture in a way that your math. prefixed (+-) are wrong because points have switched places.

Resike 04-23-13 03:24 AM

Quote:

Originally Posted by zork (Post 276950)
SDPanthom wrote an explanation on that here aswell: http://www.wowinterface.com/forums/s...7&postcount=10

Regarding your fix. Does the function only has to be called once per texture prior to any SetRotation calls?

If you have to call it after every SetRotation you will be screwed. What if you rotate the texture in a way that your math. prefixed (+-) are wrong because points have switched places.

I don't want to rotate textures after the fix, only to mirror them. Whats the point rotate texture which is incapable of it. Well, you can rotate it, but it's going to be glitchy. I only made the fix so the texture going to be look okay on 0 degree, and you can properly mirror it too.

But the version you said, seems intresting too, to cut the edges after every rotation, and you can change the -+ values based on the rotation degree, i might try to code it later.

Resike 04-23-13 09:11 AM

Okay i came up with something like that:

Code:

        if (aura.textaura ~= true) then
                texture:SetRotation(math.rad(aura.rotate));
        end
        if (aura.customtex == true) or (aura.owntex == true) then
                local ULx, ULy, LLx, LLy, URx, URy, LRx, LRy = texture:GetTexCoord();
                local x = (sqrt(2) - 1) / 2
                if string.find(aura.customname, "//") then
                        if (aura.rotate == 0) or (aura.rotate == 360) then
                                texture:SetTexCoord(ULx + x, ULy + x, LLx + x, LLy - x, URx - x, URy + x, LRx - x, LRy - x);
                        elseif (aura.rotate == 90) then
                                texture:SetTexCoord(ULx + x, ULy + x, LLx - x, LLy + x, URx + x, URy - x, LRx - x, LRy - x);
                        elseif (aura.rotate == 180) then
                                texture:SetTexCoord(ULx + x, ULy - x, LLx + x, LLy + x, URx - x, URy - x, LRx - x, LRy + x);
                        elseif (aura.rotate == 270) then
                                texture:SetTexCoord(ULx - x, ULy - x, LLx + x, LLy - x, URx - x, URy + x, LRx + x, LRy + x);
                        end
                else
                        if (aura.rotate == 0) or (aura.rotate == 360) then
                                texture:SetTexCoord(ULx + x, ULy + x, LLx + x, LLy - x, URx - x, URy + x, LRx - x, LRy - x);
                        elseif (aura.rotate == 90) then
                                texture:SetTexCoord(ULx - x, ULy + x, LLx + x, LLy + x, URx - x, URy - x, LRx + x, LRy - x);
                        elseif (aura.rotate == 180) then
                                texture:SetTexCoord(ULx - x, ULy - x, LLx - x, LLy + x, URx + x, URy - x, LRx + x, LRy + x);
                        elseif (aura.rotate == 270) then
                                texture:SetTexCoord(ULx + x, ULy - x, LLx - x, LLy - x, URx + x, URy + x, LRx - x, LRy + x);
                        end
                end
        end
        if (aura.textaura ~= true) then
                local ULx, ULy, LLx, LLy, URx, URy, LRx, LRy = texture:GetTexCoord();
                if (aura.symetrie == 1) then
                        texture:SetTexCoord(URx, URy, LRx, LRy, ULx, ULy, LLx, LLy); -- Inverse X
                elseif (aura.symetrie == 2) then
                        texture:SetTexCoord(LLx, LLy, ULx, ULy, LRx, LRy, URx, URy); -- Inverse Y
                elseif (aura.symetrie == 3) then
                        texture:SetTexCoord(LRx, LRy, URx, URy, LLx, LLy, ULx, ULy); -- Inverse XY
                else
                        texture:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy); -- Normal
                end
        end
        if (aura.textaura == true) then
                frame.baseH = 256 * aura.size * (2 - aura.torsion);
        elseif (aura.customtex == true) then
                local x = (sqrt(2) * 2) - 1
                if string.find(aura.customname, "//") then
                        if (aura.rotate == 0) or (aura.rotate == 180) or (aura.rotate == 360) then
                                frame.baseH = 256 * aura.size * (2 - aura.torsion);
                        elseif (aura.rotate == 90) or (aura.rotate == 270) then
                                frame.baseH = x * 256 * aura.size * (2 - aura.torsion);
                        else
                                frame.baseH = sqrt(2) * 256 * aura.size * (2 - aura.torsion);
                        end
                else
                        if (aura.rotate == 0) or (aura.rotate == 180) or (aura.rotate == 360) then
                                frame.baseH = 256 * aura.size * (2 - aura.torsion);
                        elseif (aura.rotate == 90) or (aura.rotate == 270) then
                                frame.baseH = 256 * aura.size * (2 - aura.torsion);
                        else
                                frame.baseH = sqrt(2) * 256 * aura.size * (2 - aura.torsion);
                        end
                end
        elseif (aura.owntex == true) then
                if (aura.rotate == 0) or (aura.rotate == 180) or (aura.rotate == 360) then
                        frame.baseH = 256 * aura.size * (2 - aura.torsion);
                elseif (aura.rotate == 90) or (aura.rotate == 270) then
                        frame.baseH = 256 * aura.size * (2 - aura.torsion);
                else
                        frame.baseH = sqrt(2) * 256 * aura.size * (2 - aura.torsion);
                end
        else
                frame.baseH = sqrt(2) * 256 * aura.size * (2 - aura.torsion);
                frame.baseL = sqrt(2) * 256 * aura.size * aura.torsion;
        end
        if (aura.textaura == true) then
                local fontsize = math.min(33, math.max(10, math.floor(frame.baseH / 12.8)));
                local checkfont = texture:SetFont(self.Fonts[aura.aurastextfont], fontsize, "OUTLINE, MONOCHROME");
                if not checkfont then
                        texture:SetFont(STANDARD_TEXT_FONT, fontsize, "OUTLINE, MONOCHROME");
                end
                frame.baseL = texture:GetStringWidth() + 5;
        elseif (aura.customtex == true) then
                local x = (sqrt(2) * 2) - 1
                if string.find(aura.customname, "//") then
                        if (aura.rotate == 0) or (aura.rotate == 360) then
                                frame.baseL = 256 * aura.size * aura.torsion;
                        elseif (aura.rotate == 90) or (aura.rotate == 270) then
                                frame.baseL = 256 * aura.size * aura.torsion;
                        elseif (aura.rotate == 180) then
                                frame.baseL = x * 256 * aura.size * aura.torsion;
                        else
                                frame.baseL = sqrt(2) * 256 * aura.size * aura.torsion;
                        end
                else
                        if (aura.rotate == 0) or (aura.rotate == 180) or (aura.rotate == 360) then
                                frame.baseL = 256 * aura.size * aura.torsion;
                        elseif (aura.rotate == 90) or (aura.rotate == 270) then
                                frame.baseL = 256 * aura.size * aura.torsion;
                        else
                                frame.baseL = sqrt(2) * 256 * aura.size * aura.torsion;
                        end
                end
        elseif (aura.owntex == true) then
                if (aura.rotate == 0) or (aura.rotate == 180) or (aura.rotate == 360) then
                        frame.baseL = 256 * aura.size * aura.torsion;
                elseif (aura.rotate == 90) or (aura.rotate == 270) then
                        frame.baseL = 256 * aura.size * aura.torsion;
                else
                        frame.baseL = sqrt(2) * 256 * aura.size * aura.torsion;
                end
        end
        PowaAuras:InitialiseFrame(aura, frame);

It lets you rotate any textures, but it shows properly "bugged" textures too at 0, 90, 180, 270 degree. Also the mirroring works on them too.

zork 04-24-13 04:06 AM

I don't really understand the hassle. Just cut out a 1px border of your texture's alpha layer. If that pixel is black the texture will be transparent thus the bug will not appear.
Blizzard uses the outmost 1 pixel for background color multiplication calculations which can be quite useful in some scenarios.

Resike 04-24-13 07:16 AM

Quote:

Originally Posted by zork (Post 276999)
I don't really understand the hassle. Just cut out a 1px border of your texture's alpha layer. If that pixel is black the texture will be transparent thus the bug will not appear.
Blizzard uses the outmost 1 pixel for background color multiplication calculations which can be quite useful in some scenarios.

Okay, and how do i do that? :P

The fix meant to work when the user loads a cusom texture, or a texture from wow.
I mostly have problems with ingame icons, i got a thread about it here: http://www.wowinterface.com/forums/s...81&postcount=5

zork 04-24-13 10:57 AM

I'm getting near alpha state.



Including pet and targettarget (showing a second ring layout template)


I decided to add a templating engine for ring setups. Thus it is possible to setup different ring types and use them for specific units.

The update and value change functions are done.

A ring can use 1,2,3 or all 4 segments.
A ring can rotate clockwise or counter-clockwise.

Lua Code:
  1. --    ring segment layout
  2. --     ____ ____
  3. --    /    |    \
  4. --    |  4 | 1  |
  5. --     ----+----
  6. --    |  3 | 2  |
  7. --    \____|____/
  8. --

More shots:
http://imgur.com/a/786JI#0

*edit*

I released oUF_Donut: http://www.wowinterface.com/download...oUF_Donut.html

zork 04-25-13 06:45 AM

This could be a possible ring template:


It combines all possible bars in one layout.

This is just one suggestion.

Health and power could have been done in two half-rings aswell.

Thus it could look like:

Seerah 04-25-13 03:11 PM

The bottom image is much easier to process than the first.

zork 04-30-13 04:22 AM

Maybe...but it has to be tested by actually using it.

The castbar will be hidden most of the time for melee players and against melee targets.

Additionally I added an optional attribute to the powerring configuration that allows hiding of the powerring if the unit does not even have power.

The good:
Testing out ring settings is really easy. It only requires an adjustment on the following variables to change the whole appearance:
Lua Code:
  1. --    ring segment layout
  2.   --     ____ ____
  3.   --    /    |    \
  4.   --    |  4 | 1  |
  5.   --     ----+----
  6.   --    |  3 | 2  |
  7.   --    \____|____/
  8.   --
  9.  
  10. --ring config
  11. radius = 0.9,     -- range 0-1
  12. sublevel = {      --display level of the texture
  13.   bg        = -8,
  14.   fill      = -7,
  15.   spark     = -6,
  16. },
  17. numSegmentsUsed = 4,  -- how many sements are affected? (see ring layout)
  18. startSegment  = 4,    -- in which segment should the ring begin it's journey? (see ring layout)
  19. fillDirection = 0,    -- how should the ring fill up? 1 = clock-wise, 0 = counter-clock-wise

http://code.google.com/p/rothui/sour...default.lua#34

Basically you can adjust the radius of a ring. Second you can adjust the texture layers. Last you set how many ring segments should be used, where the ring should start and how it should fill up.

That way you can shuffle your rings around in no time and try out new setups.

I really like adding class/combo and altpowerbar to the ring template idea. It just fits the the concept.

The problem on that is that my 16texture layers will be no more enough to hold all the layers per scrollFrame. Easy enough though. A texture drawlayer is capable of handling a sublevel and a strata. This gives us space for up to 80 textures per scrollFrame.

That should be enough >_<.

So I need to add the texture strata to the ring template. New ring elements will be "classring" and "altring".

As posted above changing the whole appearance can be done easily by changing some variables.

Why not use the comboring as an outer ring? Etc.

zork 08-07-14 06:45 AM

Released rCompassCastbar that is using the technique.

http://www.wowinterface.com/download...ssCastbar.html

semlar 02-12-16 02:59 PM

I wanted to post here because I came up with a technique based on the one outlined in this topic which can be applied to any source texture, rather than relying on semi-circles.

You start by arranging 4 textures in a grid, setting their texture coordinates so they look like a single copy of the original image.

Now our goal is to drain (or fill) each quarter by slicing the original texture from its center to one of its edges.

We can use a rotation animation to get the angle we want, but of course this also rotates our texture so it doesn't line up with the rest of the image.

However, we can use SetTexCoord to rotate our texture in the opposite direction to the rotation animation to correct its orientation.

Here's an animation to illustrate the basic concept: http://gfycat.com/BriefShowyElephantseal

The red square is where the scrollframe would normally be used to clip the edges of our rotating texture.

And this picture shows the finished design with various fill directions: http://gfycat.com/RealisticBaggyDarklingbeetle

I'll leave the script I wrote here.
Lua Code:
  1. -- Usage:
  2. -- spinner = CreateSpinner(parent)
  3. -- spinner:SetTexture('texturePath')
  4. -- spinner:SetBlendMode('blendMode')
  5. -- spinner:SetVertexColor(r, g, b)
  6. -- spinner:SetClockwise(boolean) -- true to fill clockwise, false to fill counterclockwise
  7. -- spinner:SetReverse(boolean) -- true to empty the bar instead of filling it
  8. -- spinner:SetValue(percent) -- value between 0 and 1 to fill the bar to
  9.  
  10. -- Some math stuff
  11. local cos, sin, pi2, halfpi = math.cos, math.sin, math.rad(360), math.rad(90)
  12. local function Transform(tx, x, y, angle, aspect) -- Translates texture to x, y and rotates about its center
  13.     local c, s = cos(angle), sin(angle)
  14.     local y, oy = y / aspect, 0.5 / aspect
  15.     local ULx, ULy = 0.5 + (x - 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x - 0.5) * s) * aspect
  16.     local LLx, LLy = 0.5 + (x - 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x - 0.5) * s) * aspect
  17.     local URx, URy = 0.5 + (x + 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x + 0.5) * s) * aspect
  18.     local LRx, LRy = 0.5 + (x + 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x + 0.5) * s) * aspect
  19.     tx:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
  20. end
  21.  
  22. -- Permanently pause our rotation animation after it starts playing
  23. local function OnPlayUpdate(self)
  24.     self:SetScript('OnUpdate', nil)
  25.     self:Pause()
  26. end
  27.  
  28. local function OnPlay(self)
  29.     self:SetScript('OnUpdate', OnPlayUpdate)
  30. end
  31.  
  32. local function SetValue(self, value)
  33.     -- Correct invalid ranges, preferably just don't feed it invalid numbers
  34.     if value > 1 then value = 1
  35.     elseif value < 0 then value = 0 end
  36.    
  37.     -- Reverse our normal behavior
  38.     if self._reverse then
  39.         value = 1 - value
  40.     end
  41.    
  42.     -- Determine which quadrant we're in
  43.     local q, quadrant = self._clockwise and (1 - value) or value -- 4 - floor(value / 0.25)
  44.     if q >= 0.75 then
  45.         quadrant = 1
  46.     elseif q >= 0.5 then
  47.         quadrant = 2
  48.     elseif q >= 0.25 then
  49.         quadrant = 3
  50.     else
  51.         quadrant = 4
  52.     end
  53.    
  54.     if self._quadrant ~= quadrant then
  55.         self._quadrant = quadrant
  56.         -- Show/hide necessary textures if we need to
  57.         if self._clockwise then
  58.             for i = 1, 4 do
  59.                 self._textures[i]:SetShown(i < quadrant)
  60.             end
  61.         else
  62.             for i = 1, 4 do
  63.                 self._textures[i]:SetShown(i > quadrant)
  64.             end
  65.         end
  66.         -- Move scrollframe/wedge to the proper quadrant
  67.         self._scrollframe:SetAllPoints(self._textures[quadrant])   
  68.     end
  69.  
  70.     -- Rotate the things
  71.     local rads = value * pi2
  72.     if not self._clockwise then rads = -rads + halfpi end
  73.     Transform(self._wedge, -0.5, -0.5, rads, self._aspect)
  74.     self._rotation:SetRadians(-rads)
  75. end
  76.  
  77. local function SetClockwise(self, clockwise)
  78.     self._clockwise = clockwise
  79. end
  80.  
  81. local function SetReverse(self, reverse)
  82.     self._reverse = reverse
  83. end
  84.  
  85. local function OnSizeChanged(self, width, height)
  86.     self._wedge:SetSize(width, height) -- it's important to keep this texture sized correctly
  87.     self._aspect = width / height -- required to calculate the texture coordinates
  88. end
  89.  
  90. -- Creates a function that calls a method on all textures at once
  91. local function CreateTextureFunction(func, self, ...)
  92.     return function(self, ...)
  93.         for i = 1, 4 do
  94.             local tx = self._textures[i]
  95.             tx[func](tx, ...)
  96.         end
  97.         self._wedge[func](self._wedge, ...)
  98.     end
  99. end
  100.  
  101. -- Pass calls to these functions on our frame to its textures
  102. local TextureFunctions = {
  103.     SetTexture = CreateTextureFunction('SetTexture'),
  104.     SetBlendMode = CreateTextureFunction('SetBlendMode'),
  105.     SetVertexColor = CreateTextureFunction('SetVertexColor'),
  106. }
  107.  
  108. local function CreateSpinner(parent)
  109.     local spinner = CreateFrame('Frame', nil, parent)
  110.    
  111.     -- ScrollFrame clips the actively animating portion of the spinner
  112.     local scrollframe = CreateFrame('ScrollFrame', nil, spinner)
  113.     scrollframe:SetPoint('BOTTOMLEFT', spinner, 'CENTER')
  114.     scrollframe:SetPoint('TOPRIGHT')
  115.     spinner._scrollframe = scrollframe
  116.    
  117.     local scrollchild = CreateFrame('frame', nil, scrollframe)
  118.     scrollframe:SetScrollChild(scrollchild)
  119.     scrollchild:SetAllPoints(scrollframe)
  120.    
  121.     -- Wedge thing
  122.     local wedge = scrollchild:CreateTexture()
  123.     wedge:SetPoint('BOTTOMRIGHT', spinner, 'CENTER')
  124.     spinner._wedge = wedge
  125.    
  126.     -- Top Right
  127.     local trTexture = spinner:CreateTexture()
  128.     trTexture:SetPoint('BOTTOMLEFT', spinner, 'CENTER')
  129.     trTexture:SetPoint('TOPRIGHT')
  130.     trTexture:SetTexCoord(0.5, 1, 0, 0.5)
  131.    
  132.     -- Bottom Right
  133.     local brTexture = spinner:CreateTexture()
  134.     brTexture:SetPoint('TOPLEFT', spinner, 'CENTER')
  135.     brTexture:SetPoint('BOTTOMRIGHT')
  136.     brTexture:SetTexCoord(0.5, 1, 0.5, 1)
  137.    
  138.     -- Bottom Left
  139.     local blTexture = spinner:CreateTexture()
  140.     blTexture:SetPoint('TOPRIGHT', spinner, 'CENTER')
  141.     blTexture:SetPoint('BOTTOMLEFT')
  142.     blTexture:SetTexCoord(0, 0.5, 0.5, 1)
  143.    
  144.     -- Top Left
  145.     local tlTexture = spinner:CreateTexture()
  146.     tlTexture:SetPoint('BOTTOMRIGHT', spinner, 'CENTER')
  147.     tlTexture:SetPoint('TOPLEFT')
  148.     tlTexture:SetTexCoord(0, 0.5, 0, 0.5)
  149.    
  150.     -- /4|1\ -- Clockwise texture arrangement
  151.     -- \3|2/ --
  152.  
  153.     spinner._textures = {trTexture, brTexture, blTexture, tlTexture}
  154.     spinner._quadrant = nil -- Current active quadrant
  155.     spinner._clockwise = true -- fill clockwise
  156.     spinner._reverse = false -- Treat the provided value as its inverse, eg. 75% will display as 25%
  157.     spinner._aspect = 1 -- aspect ratio, width / height of spinner frame
  158.     spinner:HookScript('OnSizeChanged', OnSizeChanged)
  159.    
  160.     for method, func in pairs(TextureFunctions) do
  161.         spinner[method] = func
  162.     end
  163.    
  164.     spinner.SetClockwise = SetClockwise
  165.     spinner.SetReverse = SetReverse
  166.     spinner.SetValue = SetValue
  167.    
  168.     local group = wedge:CreateAnimationGroup()
  169.     local rotation = group:CreateAnimation('Rotation')
  170.     spinner._rotation = rotation
  171.     rotation:SetDuration(0)
  172.     rotation:SetEndDelay(1)
  173.     rotation:SetOrigin('BOTTOMRIGHT', 0, 0)
  174.     group:SetScript('OnPlay', OnPlay)
  175.     group:Play()
  176.    
  177.     return spinner
  178. end
  179.  
  180. ----------
  181. -- Demo
  182. ----------
  183.  
  184. local spinner1 = CreateSpinner(UIParent)
  185. spinner1:SetPoint('BOTTOMRIGHT', UIParent, 'CENTER', -2, 2)
  186. spinner1:SetSize(64, 64)
  187. spinner1:SetTexture('interface/icons/inv_mushroom_11')
  188.  
  189. spinner1:SetClockwise(false)
  190. spinner1:SetReverse(false)
  191.  
  192. local spinner2 = CreateSpinner(UIParent)
  193. spinner2:SetPoint('BOTTOMLEFT', UIParent, 'CENTER', 2, 2)
  194. spinner2:SetSize(64, 64)
  195. spinner2:SetTexture('interface/icons/inv_mushroom_11')
  196.  
  197. spinner2:SetClockwise(true)
  198. spinner2:SetReverse(false)
  199.  
  200. local spinner3 = CreateSpinner(UIParent)
  201. spinner3:SetPoint('TOPRIGHT', UIParent, 'CENTER', -2, -2)
  202. spinner3:SetSize(64, 64)
  203. spinner3:SetTexture('interface/icons/inv_mushroom_11')
  204.  
  205. spinner3:SetClockwise(true)
  206. spinner3:SetReverse(true)
  207.  
  208. local spinner4 = CreateSpinner(UIParent)
  209. spinner4:SetPoint('TOPLEFT', UIParent, 'CENTER', 2, -2)
  210. spinner4:SetSize(64, 64)
  211. spinner4:SetTexture('interface/icons/inv_mushroom_11')
  212.  
  213. spinner4:SetClockwise(false)
  214. spinner4:SetReverse(true)
  215.  
  216. local f = CreateFrame('frame')
  217. local timespent = 0
  218. f:SetScript('OnUpdate', function(self, elapsed)
  219.     timespent = timespent + elapsed
  220.     if timespent >= 3 then
  221.         timespent = 0
  222.     end
  223.    
  224.     local value = timespent / 3
  225.     spinner1:SetValue(value)
  226.     spinner2:SetValue(value)
  227.     spinner3:SetValue(value)
  228.     spinner4:SetValue(value)
  229. end)

sezz 02-12-16 03:58 PM

Quote:

Originally Posted by semlar (Post 312993)
Here's an animation to illustrate the basic concept: http://gfycat.com/BriefShowyElephantseal

Funny, this is how I implemented cooldown spirals in WildStar in 2014... and then removed the code 1 or 2 days later when I found out I can do it with their progress bar control... :o

But it's good to see that the idea wasn't bad at all :)

zork 02-14-16 11:06 AM

Semlar that is fucking brilliant!

semlar 02-14-16 04:20 PM

While it has to start or end at a 90 degree angle, you can still create arbitrary arcs using transparent textures and adjusting your value to compensate for the offsets.

Here's an example: http://gfycat.com/VioletJauntyGelding

This is the source image:


zork 02-15-16 03:00 AM

Hmmm...semlar what happens if one wants multiple rings per segment? (Like mana and life)
They both need their own spinner right? Is overlaying a problem?

From my work with orbs I can tell that frame stacking is a pain in the but. In the system that is working with only two scrollframes (two halfrings) one can position multiple textures inside the scrollchild. Textures can be stacked amazingly well thanks to texture drawLayer.

To get frame stacking right on my orbs I have to parent each frame after another.

Quote:

background > scrollframe > overlay > fontstrings
*Sidenote*
Just to save it from dying. I recoverd my blogpost from elitistjerks from 2009 and brought it to github.
https://github.com/zorker/rothui/tre...chive/rRingMod
https://web.archive.org/web/20110208.../362-ring.html

semlar 02-15-16 02:14 PM

Quote:

Originally Posted by zork (Post 313047)
Hmmm...semlar what happens if one wants multiple rings per segment? (Like mana and life)
They both need their own spinner right? Is overlaying a problem?

We might need to create another scroll frame that covers the spinner and parent the 4 background textures to its scroll child to keep them on the same level as the wedge texture.

I want each spinner to be treated as one unit and separate from any other spinners that you create.

zork 02-29-16 02:50 AM

I want to play around with semlars function this week. Currently collecting some ideas and links.

http://wowwiki.wikia.com/wiki/SetTex...ransformations
https://github.com/tomrus88/Blizzard...L/Util.lua#L31

I have not grasped how it is possible to rotate the wedge texture via animation rotation and correct that rotation via SetTexCoord.

Like you rotate it to the right by 45° but then you call SetTexCoord to rotate it left by -45°. How is it keeping the clipping?

Oh. It is the other way around isn't it? You do SetTexCoord first and then rotate.

semlar 02-29-16 06:57 AM

The order of the rotations is irrelevant, they're rotated in opposite directions to keep the picture level while the animation creates the desired angle. I thought of all of this immediately after seeing this image in your original post:



The yellow square is the slice/wedge texture; its corner is attached to the center of the image and an animation widget is being used to rotate it around in a circle to create the (green) angle that we want.

I'll make some illustrations to hopefully clarify what's going on. Here's what we're starting with:



First, we rotate our image using an animation. This gives us our angle, but of course it also rotates the image.



We'll apply a rotation in the opposite direction to correct its orientation using SetTexCoord.



It's upright, but not quite the effect we're going for, so let's shift it to the left (actually halfway down and halfway to the right, we want it to be centered on one of its corners so it lines up with the image). This translation is done along with the rotation in one matrix transformation to generate the coordinates for SetTexCoord, but I'm showing both steps separately here.



Finally, we'll put it in a scrollframe to clip anything outside of the quarter of the image we actually want to be displayed.



That's it, the rest of the image is just 3 copies of the original texture shifted halfway to the center to make up each quarter.



Here's our final product:


zork 02-29-16 10:02 AM

Thanks a ton. What blew me is that you can adjust the SetTexCoord of a texture and keep the clipping that is set by the animation rotation.

Basically the texture is clipped twice. By the animationgroup and by the scrollframe.

There are huge benefits being able to do it this way because the ring texture can be of any shape.

Is the outcome any different when using this instead of the animationgroup?
http://wowprogramming.com/docs/widge...re/SetRotation

Yukyuk 02-29-16 02:20 PM

A few weeks ago semlar allowed me to use the code he posted to use it in an addon.
Its far from finished, here are the first results.

First picture is Health and mana with red and blue Spinners (called so because thats the word semlar used in his example :) )
There is an animation there below the spinner but of course that isn't visible in this picture :rolleyes:



Second picture is the health Spinner in action.



Third and fourth pictures are the same as the first two but have different textures applied.
Also the "eye" in the middle is animated.





Early january I got the inspiration for an animated heath/mana bar.
Found Zork's addon called Diso Kugel 2.
But couldn''t get the result I wanted :mad:
Then came semlar's post.
Spinners (name for the addon I am using) is a combination of the code semlar posted and the inspiration I got after seeing Disco Kugel 2 :D

Might be a few weeks before I will release a Beta version (progress is limited by time and skill).
But so far I am happy with it.

Any suggestions for improvements are most welcome.

SDPhantom 02-29-16 03:00 PM

Quote:

Originally Posted by zork (Post 313301)
Is the outcome any different when using this instead of the animationgroup?
http://wowprogramming.com/docs/widge...re/SetRotation

Texture:SetRotation() reuses the C code for Texture:SetTexCoord() using a rotation matrix (and shrinks the image by √2), so they overwrite each other.

semlar 02-29-16 08:06 PM

Quote:

Originally Posted by zork (Post 313301)
Thanks a ton. What blew me is that you can adjust the SetTexCoord of a texture and keep the clipping that is set by the animation rotation.

Basically the texture is clipped twice. By the animationgroup and by the scrollframe.

The animation isn't clipping the texture. The only thing the animation does is physically rotate the entire texture widget, which is extremely important because SetTexCoord is only capable of moving the texture within the boundaries of its (square) dimensions.



Since the animation rotates the entire physical texture object, it means SetTexCoord is no longer limited to cutting off the texture at 90 degree angles (the sides of the texture), because now the side of the texture is at whatever angle we rotated it to.

You can think of a texture object like a scroll frame. You can move its contents around using SetTexCoord, but you can only ever "clip" it at its edges, which are always 90 degrees.

Now imagine that you could apply a rotation animation to a scroll frame. You're no longer limited to 90 degree angles because the edges aren't straight up and down, they're at the angle you set the rotation to.

The animation still isn't clipping anything in that example, the scroll frame is, it's just changing the angle that the scroll frame is clipping its contents at.

zork 03-01-16 05:21 AM

Hmmm. When working with textures that use an aspect of 1 (square), is the following condensed Transform function correct?

Lua Code:
  1. local mcos, msin = math.cos, math.sin
  2. local function Transform(texture, angle)
  3.   local c,s = mcos(angle), msin(angle)
  4.   local ULx, ULy = 0.5-c+s, 0.5-c-s
  5.   local LLx, LLy = 0.5-c, 0.5-s
  6.   local URx, URy = 0.5+s, 0.5-c
  7.   local LRx, LRy = 0.5, 0.5  
  8.   texture:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
  9. end

semlar 03-01-16 10:54 AM

Quote:

Originally Posted by zork (Post 313319)
Hmmm. When working with textures that use an aspect of 1 (square), is the following condensed Transform function correct?

Lua Code:
  1. local mcos, msin = math.cos, math.sin
  2. local function Transform(texture, angle)
  3.   local c,s = mcos(angle), msin(angle)
  4.   local ULx, ULy = 0.5-c+s, 0.5-c-s
  5.   local LLx, LLy = 0.5-c, 0.5-s
  6.   local URx, URy = 0.5+s, 0.5-c
  7.   local LRx, LRy = 0.5, 0.5  
  8.   texture:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
  9. end

Yeah, if you're only manipulating square textures it looks like that does the same thing as calling Transform(-0.5, -0.5, angle, 1) with the function I wrote.

If you'd rather work with degrees instead of radians, I believe the blizzard functions sin and cos are degree-based instead of the radian-based math.sin and math.cos, so you don't even have to convert between them if you use those instead.

zork 03-01-16 12:45 PM

Not sure if you noticed it. The wierd bug that you fixed in the demo with a OnUpdate function that you call onPlay and disable it thereafter can be fixed by just calling :Pause() after :Play().

What cannot be removed though is the delay. No clue why it does not animate without it.

Lua Code:
  1. --animationgroup
  2.         local group = wedge:CreateAnimationGroup()
  3.         local rotation = group:CreateAnimation('Rotation')
  4.         rotation:SetOrigin('BOTTOMRIGHT', 0, 0)
  5.         rotation:SetDuration(0)
  6.         rotation:SetEndDelay(1)
  7.         group:Play()
  8.         group:Pause()
  9.         spinner._rotation = rotation

SDPhantom 03-01-16 01:06 PM

The delay makes sure you have some time before the animation ends. Otherwise, the animation stops and snaps back to the original position before you get a chance to pause it. I'm not entirely sure if AnimationGroup:SetLooping("REPEAT") would crash the game with a zero duration or if it would apply at all, but that might be a possibility.

zork 03-01-16 02:09 PM

SDPhantom the thing is that we never need that delay. If we do not set it the API will not rotate the texture.

I sat down and wrote myself a small test addon for the ring. Super cool indeed. That the new technique allows texture stretching makes it even better.

http://imgur.com/a/fGZpG

https://github.com/zorker/rothui/tre.../wow6.0/rRingo

What is missing is the ability to select another start segment and to pick the number of frames to be used.

So many use cases. You could use it to create small squares that emulate a cooldown spiral.

Lua Code:
  1. --spinner1:SetTexture("interface/icons/inv_mushroom_11")
  2. local texture = spinner1:CreateTexture()
  3. texture:SetTexture(1,1,1)
  4. spinner1:SetTexture(texture:GetTexture())
  5. spinner1:SetVertexColor(1,0,0)

By far the coolest thing in a long time.

I would not use the animation system later on for smooth animation progress. What oUF_Smooth does is more than fine. All one needs is a SmoothBar module for all the value updates. Sth like this: https://github.com/zorker/rothui/blo...oUF_Smooth.lua

SDPhantom 03-01-16 02:53 PM

Quote:

Originally Posted by zork (Post 313327)
SDPhantom the thing is that we never need that delay. If we do not set it the API will not rotate the texture.

"Needing" it is subjective. Do we need a full 1 sec end delay? No. In fact, it could be far less. As long as it keeps the animation running long enough so we can pause it. The problem with running a zero duration animation is it never plays. This can either be a check in C code to not start or the animation ends before AnimationGroup:Play() even returns. Either way produces the same result as when an animation finishes, everything snaps back to their original layout.

Your own testing provides this answer, I'm just explaining it so you can understand what might be going on and why.

zork 03-02-16 05:53 AM

Thanks. Maybe it is just me but I find it wierd that the animation has to be played and then paused to be able to use :SetRadians().

On top of that you cannot play/pause the animation itself. It has to be the group.

sigg 03-02-16 10:22 AM

Hello

Thanks Zork to point me there.

It is a very nice concept from semlar.

Cheers
Sigg

SDPhantom 03-02-16 02:57 PM

Quote:

Originally Posted by zork (Post 313362)
Thanks. Maybe it is just me but I find it wierd that the animation has to be played and then paused to be able to use :SetRadians().

On top of that you cannot play/pause the animation itself. It has to be the group.

What bothers me are the numerous bugs still in the animation system. For example, rotation animations don't reposition the frame's children, they just rotate them in place on the same origin point. Also, setting a particular animation's target only works in XML, the Lua API for it does nothing (always runs on the AnimationGroup's parent no matter what you set the target to).

Resike 03-02-16 04:11 PM

Would it be possible to create animated pie charts with this method with relatively small cost?
I'm looking for something like that in the future.

semlar 03-02-16 04:38 PM

Quote:

Originally Posted by Resike (Post 313367)
Would it be possible to create animated pie charts with this method with relatively small cost?
I'm looking for something like that in the future.

I actually wrote this specifically to be used as an option for progress textures in weak auras, so it will be used to create animations there.

Most of the processing is from performing the matrix transformation for the texture coordinates which requires a decent number of math operations, but even doing this with a number of different textures probably isn't going to cause a noticeable impact on most, if any, computers capable of running the game in the first place.

edit: I tested 1200 spinners (all using the same texture) and went from 100 fps to around 80-85, animating them OnUpdate.

SDPhantom 03-02-16 05:57 PM

I was actually more interested in data relating to the additional impact of having paused animations continuously rendering. An earlier version of my custom flight HUD used a bounce looping method on rotating textures and paused whenever the loop state changed. I scrapped the method since it not only had its own problems to deal with, but the entire addon as a whole was eating up a considerable chunk of processing power when the game really needed it. It wasn't the worst part of the old code, but I did consider it to be contributing factor.


All times are GMT -6. The time now is 12:14 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI