Jump to content

Help Needed to save my Game - Face Flipping


Loki Eliot
 Share

You are about to reply to a thread that has been inactive for 4037 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Ive run into a bug that occurs when an object thats animated useing faceflipping is turned into a Pathfinder Character. Mainly it dissapears or fails to rezz visible.

Ive tried all sorts of work arounds with so far no success in keeping the object visible while pathfinding.

One idea i have is maybe the way my Faceflipping script works is conflicting with pathfinding some how and was wondering if anyone could suggest other ways i could get the same face flipping effect.

 

integer running;
integer count;
integer side;

default
{
    state_entry()
    {
        if(!running) llSetTimerEvent(.08);
        else llSetTimerEvent(.0);
        running = !running;
    }
    
    timer() {
        ++count;
        if (count == 7) count = 1;
        if (count == 1) side = 0;
        else if (count == 2) side = 1;
        else if (count == 3) side = 2;
        else if (count == 4) side = 3;
        else if (count == 5) side = 4;
        else if (count == 6) side = 5;
        else if (count == 7) side = 6;
        llSetAlpha(0, ALL_SIDES);
        llSetAlpha(100, side);
    }    
}

 

Link to comment
Share on other sites

(Just for tidiness, llSetAlpha takes a float argument of the actual alpha value of 0.0 to 1.0, not an integer percentage, but that's not the problem here. Also, if one were to use this approach, you might want to replace the two llSetAlpha calls with one combined llSetLinkPrimitiveParamsFast() call to halve the number of object updates and hence halve the network lag. But you may not want to use this approach anyway, about which more below.)

If I'm seeing what you're seeing, it seems to be a viewer bug, but I'm not finding a match for it in Jira (I'm not closely watching Pathfinding bugs these days, so it may be there somewhere). If one turns on Develop / Show Info / Show Updates to Objects, the updates are shown to keep flowing even after the object eventually disappears from the viewer. Also, in my testing, I can always get the object to reappear by camming away from it enough, and then it will stay visible for some time before disappearing again. So I think the sim is doing what it's supposed to, but the viewer just stops displaying the object at some point. If that's right, and the sim is sending what it should, it may be difficult for a script to "trick" the viewer into paying attention.

So I'd suggest fillng a viewer bug unless somebody else knows there's already one in the jira.

Meanwhile, however, if you're doing what I think you're doing, you might get the same effect with much less lag by remapping the "sides" of your (Mesh, I'm assuming) object onto a single material UV map, and then using texture animation to control which bit of the whole UV map is showing. This does use a very sparse texture (with 7 mutually exclusive sides, 6/7ths of the texture would be alpha'd out, and the texture detail for all 7 sides crammed into the remaining 1/7th of the texture), and is only feasible for objects with unchanging textures, so maybe that's not workable for your application. If it is workable, however, it removes the need for an active script at all, once the animation starts, and reduces object updates over the network to zero.

Link to comment
Share on other sites

Thanx yes, i got extra help from someone with the Faceflipping and we sort of ruled out This as being the specific cause.

The idea you have for animating texture rather than face flipping is sound, but would indeed mean cramming in alot of smaller textures for my model so im very reluctant to use that, thanx anywas for the suggestion.

I will probably open a JIra next week after ive finished researching the problem more. :)

Link to comment
Share on other sites

:)  That was my first thought too, so in fact I tried it and it didn't help. (Well, I toggled hovertext content inside a llSLPPF() along with the alpha-flipping, but I think that has the same effect.) That was why I turned on object updates, because AFAIK, the hovertext trick was to convince the server to send a full object update.  As it turned out, those updates were evidently arriving at the viewer, but the viewer was simply not drawing the object at all after a while.

Link to comment
Share on other sites

I think part of your problem might be the timer value..  it is extremely small.  While it may have worked when the object was not processing any other events, adding pathfinding to the object might be enought to cause your timer events to back up and overflow the event queue.  It is NOT an infinite queue, and it has to handle all of the events sent.  Using the fast version of SetPrimPrams might help reduce the processing time for event handling and suck them out faster, prolonging the time until it overflows, but I would also suggest testing with high timer values to see if reducing the flip rate helps too.

Link to comment
Share on other sites

if is a tiny timer issue then can maybe try like

 

float TIME_BETWEEN_DO = .08;state_entry(){   llSetTimerEvent(TIME_BETWEEN_DO); //start}timer(){   llSetTimerEvent(.0); //stop   // do big long stuff ...   llSetTimerEvent(TIME_BETWEEN_DO); //continue}

 

other one is can do a statechange in the timer. so to suspend the defaulttimer until the statechange is finished. this the proper way to do it. but the way above is ok if more used to linear/topdown style programming

statechange something like

 

integer running;integer count;integer side;default{    state_entry()    {        if(!running) llSetTimerEvent(.08);        else llSetTimerEvent(.0);        running = !running;    }        timer()     {	state alpha;            }    }state alpha{    state_entry()    {	++count;        if (count == 7) count = 1;        if (count == 1) side = 0;        else if (count == 2) side = 1;        else if (count == 3) side = 2;        else if (count == 4) side = 3;        else if (count == 5) side = 4;        else if (count == 6) side = 5;        else if (count == 7) side = 6;        llSetAlpha(0, ALL_SIDES);        llSetAlpha(100, side);        state default;    }}

 

edit add:

just say that don't need the running flag in this state way. can just go in the default state_entry

state_entry() { llSetTimerEvent(.08) };

and thats it

a complete example would be something like

integer side = 0;default{    state_entry()    {	llSetTimerEvent(.08);    }        timer()     {	state alpha;            }    }state alpha{    state_entry()    {        llSetAlpha(.0, ALL_SIDES);        llSetAlpha(1., side);        ++side;        if(side == 7) side = 0;	         state default;    }}

 

Link to comment
Share on other sites

altho (:

if was me then I probably have 3 states. to avoid flicker in this case and add a teeny tiny bit of more efficient by not apply ALL_SIDES on every timer

having a main state separate from the default state means that can have a initialise section for script start and a separate one for your runtime. e.g:

 

integer side = 0;default{    state_entry()    {        llSetAlpha(.0, ALL_SIDES);        llSetAlpha(1., side);        state main    }}state main{    state_entry()    {	llSetTimerEvent(.08);    }        timer()     {	state alpha;            }    }   state alpha{    state_entry()    {        llSetAlpha(.0, side);        ++side;        if(side == 7) side = 0;	         llSetAlpha(1., side);        state main;    }}

 

 edit add

the above is not actual total code safe. so I add the safety part below. is to turn off the timer in main state_exit

 

 

state main{    state_entry()    {	llSetTimerEvent(.08);    }        timer()     {	state alpha;            }    state_exit()    {	llSetTimerEvent(.0);    }    }   

 

 

 

Link to comment
Share on other sites

The problem has already been identified experimentally as an event buffer overflow caused by a timer value that is too small.    Why would you solve that by ADDING a State change ( which FLUSHes the event buffer) to the mix?

LSL State info  sez...

On state change:

  • All listens are released.
  • The event queue is cleared. (see Notes for a partial workaround)

Adding a state change in the manner you have suggested might seem to keep the object flickering,  but at the cost of (probably) dumping  other events awaiting processing.   The O.P.  suggested the object also did pathfinding.  This suggestion most likely would result in pathfinding events getting tossed and break that functionality in obscure ways.

You do NOT need to make the script as complicated as these last 2 examples...  The solution is making display processing as fast as possible  and increase the time between events..  Change your timer value from 0.08 to 0.2 and see if the problem remains.  Reduce the timer value in increments until the problem returns,  and then bump it back up to give yourself some headroom when the object is in a sim that might be a little slow.

 

// fast face flipping for a cube..   Experiment with values for the timer to find a minimum working valuefloat delay = 0.2;integer count=0;integer oldside=0;default {    state_entry()    {           llSetTimerEvent(delay);        llSetAlpha(0, ALL_SIDES);    }timer()    {         ++count;                 if (count == 7)             count = 0;                                    llSetAlpha(0, oldside); llSetAlpha(1,count);        oldside = count;    }}

 

 

Link to comment
Share on other sites

This is an interesting discussion, but I don't think it's the problem I saw when I tested Loki's sample code.

There's no mechanism I can imagine by which moving the cam around can fix an event buffer overflow.

Also, AFAIK, the result of an event buffer overflow is that some events are lost, but these events are simply clock ticks, so maybe there'd be some barely perceptible hesitation in the flipping of faces, but not a complete freeze with all faces transparent.

Moreover, even when frozen, the viewer was getting object updates, it just wasn't drawing the object that generated those updates.

I can believe that a slower rate of update may prevent or delay or reduce the likelihood of triggering this problem, but what I saw was a viewer problem.

Link to comment
Share on other sites


Dz Delicioso wrote:

The problem has already been identified experimentally as an event buffer overflow caused by a timer value that is too small.    Why would you solve that by ADDING a State change ( which FLUSHes the event buffer) to the mix?

  sez...

On state change:
  • All
    are released.
  • The event queue is cleared. (see
    for a partial workaround)

Adding a state change in the manner you have suggested might seem to keep the object flickering,  but at the cost of (probably) dumping  other events awaiting processing.   The O.P.  suggested the object also did pathfinding.  This suggestion most likely would result in pathfinding events getting tossed and break that functionality in obscure ways.

You do NOT need to make the script as complicated as these last 2 examples...  The solution is making display processing as fast as possible  and increase the time between events..  Change your timer value from 0.08 to 0.2 and see if the problem remains.  Reduce the timer value in increments until the problem returns,  and then bump it back up to give yourself some headroom when the object is in a sim that might be a little slow. 

 

sorry. I not mean to upset anyone

i only mention proper way bc LSL is a state engine by design. so was just give example of how events are handled by state engines

OP say has this problem and makes a example script. so out of this has comes 3 alternatives ways to think about how to make a solution

1) lengthen the timer interval

2) stop the clock

3) use states

one of the things inherent to state engines is that each state take and release resources as it needs them. so is only in the design sense is it proper

can make a single state and do all in that one state which have the advantage of lending itself to linear/top down style programming. which is what many people are comfortable with programming wise

but it do introduce other factors. like having to recreate/replicate in code the concept of state

and in this example finding the optimal timer interval

the main difficulty in doing the one state way is actual estimating what is the optimum timer interval for the next script process. when estimating this then also have to factor in what is the competition in the runtime environment where the script is competing for resources with other scripts. some sims environments light loaded. others heavy. etc. so in critical situations we then end up writing code that check sim stats before executing the next script process. and so on

which is what you mention also. so we agree on that

is ok to do this way tho but the main consideration/drawback is that can often end up with heaps of LSL code that recreate/replicate the functionality of the builtin state engine

+

with things like pathfinding and listens etc then can look at the design purpose of state engines. the design is such to allow multiple processes to run simultaneously. the LSL state engine was designed with this in mind

like if need to add a listen to this example object then by design we put it in a separate script. not in this script. this script just do the alpha change thing. consistently over and over without having to factor in other things that might be going on in the scripted object. and also works nicely together with everything else running on the simulator

in the state engine design, llListen being for another purpose goes in another script. pathfinding in another and so on. the scripts pass messages to each other when they have to

is when we start to try do all in one script then can sometimes end up fighting against the state engine itself and end up also writing lots of complicated code uneccessarily sometimes

+

am just chatting about state engines here now. like how they work and that. why they designed like they are. what is their point. just so people can consider and think about

lots of little scripts doing one thing each is better for a state engine simulator overall performance than fewer scripts executing their own state engine interpreters. in this case coded in LSL

can see with OP example how is a state engine already been created in LSL code. the use of a running flag. like based on the state of a global flag then do this or do that

the use of the global running flag is quite a bit different from the use of the global side variable. the side variable is a data store. the running flag is directing script execution flow based on state

Link to comment
Share on other sites


16 wrote:

if is a tiny timer issue then can maybe try like

 
float TIME_BETWEEN_DO = .08;state_entry(){   llSetTimerEvent(TIME_BETWEEN_DO); //start}timer(){   llSetTimerEvent(.0); //stop   // do big long stuff ...   llSetTimerEvent(TIME_BETWEEN_DO); //continue}

 

I usually do timer events this way, unless the event handler looks to be faster than stopping and starting the timer, as I then don't have to worry about crashing the script if my event handler takes too long. It's difficult to determine how long an event handler will take to execute, both because of its internal complexity and external server lag. The resulting variabiility in firing rate is (to me at least) less problematic than script failure.

Link to comment
Share on other sites

I've reported an issue to the Jira, which due to the awful changes most people aren't going to be able to see:

https://jira.secondlife.com/browse/BUG-2116?

If you know the secret handshake you'll be able to view it. Basically I own some breedables called Dwarfins and sometimes when I login I can't see them, I'll see this:

InvisibleDwarfins.jpg

The guy on the left should actually have fellows all over the screen who look like him, also in the picture are their weapons, which happily display. The book appears when you click a Dwarfin and order it to read, when I do that their hair or hat appears but not the rest of them.

If I move to another room and come back, the issue persists, however if I teleport out and come back, all seems fine:

VisibleDwarfins.jpg

Now the reason I'm bringing this here is because the person who looked at the issue with Loki, suggests the issue I'm reporting looks very similar. I'm not so sure about that but it may be that the root cause of the problem is the same as the problem Loki is experiencing.

Link to comment
Share on other sites

yes. how fast/often an event occurs is dependent on what else is happening in the environ. in multi-process environs then this is most often outside of our direct control

so if say set an event to occur at 0.08 intervals then the interval is relative to everything else that is happening. best we can obtain is the event occurring at a rate not less than 0.08

by managing the interval between our events occuring then we are better placed to ensure process safety. as when we try to manage the absolute time for our process to run to completion then bc of the environ beyond our control there is no way to guarantee safety. like that the process will always complete in the time allotted for it by our script

+

is a bit unfortunate the way llTimerEvent is named. as the wording can sometimes lead us to believe that the event will occur at regular times. which is not true. the event occur at regular intervals. intervals which by absolute clocktime can vary depending on what else is happening in the same time window

am guilty of this myself tho. like i use the words time and interval interchangeably. which is not the best thing for me to do when discuss these kinda things

Link to comment
Share on other sites

The followup posts and images do point to the interest list problems recently introduced.   The code in the OP & JIRA certainly didnt indicate the objects were mesh, or that TP's or re-logging would resolve the issue.

I still take exception to scripting examples that decrease the efficiency of the simple solution.   Proposing to ADD state changes to a script that is struggling to perform its current workload is a poor design choice that impacts everyone.   Certainly it is more efficient to change the timer value than to ADD approximately 24 state changes AND 24 llSetTimerEvent calls to each second of script processing time.   'nuff said.

Link to comment
Share on other sites


The code in the OP & JIRA certainly didnt indicate the objects were mesh, or that TP's or re-logging would resolve the issue.

The objects don't have to be mesh. I got my results using a regular 0.5m cube (just because I was too lazy to hunt my inventory for a mesh with enough faces to flip), and I think what I saw was the same thing Loki described.

The fact that moving the cam around enough will trick the viewer into drawing the object again does sort of fit with an interestlist-related origin. I am, however, a bit skeptical of this problem being a simple result of those interest list changes. The reason is that the Show Updates To Objects sprites continue to flow from the object even after its faces are no longer being drawn by the viewer. I assume that those sprites are created by the viewer any time it gets an object update, so whatever the object's state on the interestlist, updates are still getting to the viewer (and the viewer knows the location of the updated object) even though it's not drawing the object anymore.

It may well be that the interestlist changes in the sim triggered some long-dormant rendering bug in the viewer. Or maybe, with the interestlist changes, the sim gets into a state in which it sends malformed updates after a while. Or maybe it's just a viewer bug unrelated to interestlist.

Link to comment
Share on other sites


Dz Delicioso wrote:

The followup posts and images do point to the interest list problems recently introduced.   The code in the OP & JIRA certainly didnt indicate the objects were mesh, or that TP's or re-logging would resolve the issue.

I still take exception to scripting examples that decrease the efficiency of the simple solution.   Proposing to ADD state changes to a script that is struggling to perform its current workload is a poor design choice that impacts everyone.   Certainly it is more efficient to change the timer value than to ADD approximately 24 state changes AND 24 llSetTimerEvent calls to each second of script processing time.   'nuff said.

is two ways can write software. can write code safe so that an event will fire and execute to completion every time. or can write in a way that the expected event and process should occur. and most times it does. except on the sometimes when it don't bc of things outside of our control. like event queue buffer overflow

if for example we extend the interval to .20 or 1.0 or 2.0 or 2000.0 etc for any process how can we guarantee in this environ that the event queue buffer wont overflow?

do we care about this? is it important? is it critical? 

+

for example. take a job

a requirement of the job is that a event process will fire in sequenced steps of 4 and then repeat. each step dependent on the outcome/result of the last. a further requirement is that the process must yield to other processes outside of its control. while also maintaining the integrity of the process   

how do we guarantee integrity? we can stop the clock. if we don't then the buffer (outside of our control) can overflow leading to:  0.1.3.0.1.2.3.1.2.3 etc. this may not be a problem if using a simple accumulator operation. it do tho become problematic when move beyond this

+

yes the OP is a light example for a deep discussion of state engines. but it do help highlight these things as a talking point

OP say he have this problem with stuff not showing when it should

to know for absolute sure that is not a timer problem causing event buffer overflow affecting the outcome adversely then can just stop/pause the clock between. when do this then the buffer will only ever have 1 event waiting in the buffer. ever. at any given instant. 

if the problem does not resolve itself just by stopping the clock preventing the event from ever firing while the process is running then is something else causing the problem

+

the last code example using states actual does do the same thing from a code safety pov as the 1st code example I made.

which then lead to to more deep discussion about state engines themselves. which now lead to the efficiency of the LSL state engine itself in allocating resources. which is a interesting discussion in itself

  

Link to comment
Share on other sites

yes could be

can be seen as similar to the camera problem we was having with vehicles

with the interest list the way is supposed to work is that the viewer exchanges a primary interest list with the server based on the viewer original camera position. thereafter the sim server only sends down changes/updates that are outside of the original camera view when the camera view swings/changes while we stay on the same sim

if cross to a new sim then get a new primary interest list and start over

Ciaran seeing the same effect. like go to another room and come back. is no update of the original resources in the view. only new resource changes that have occurred since are listed as of interest. but when TP away and come back then get all new interest list

for the vehicle problem it was found that the viewer camera position was being calculated to not be in the position it should be. so that was fix as I understand it

it maybe also the case here. or at least the root cause of it

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4037 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...