Jump to content

Glow when walking on it?


Giyua
 Share

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

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

Recommended Posts

Hello all I've been looking for a script that will glow when an avatar walks on it. I can't seem to find one. There is one on mp but it's not full perm so I'd have to make my own and I have no clue about how to even begin that kind of script.

 

Edit- I found this but I want it to glow bright upon stepping on it and turn off after you get off of it

integer is_on = FALSE;
float glow = .1;
default
{
    collision_start(integer num_detected) 
    {
        if(!is_on)
        {
            float i;
            for(i = 0.0; i < glow; i += 0.020 )
            {
                llSetPrimitiveParams([PRIM_GLOW, ALL_SIDES, i]);
                //llSleep(1.0);
            }
            is_on = TRUE;
        }
    }

    collision_end(integer num_detected) 
    {
        if(is_on)
        {
            float i;
            for(i = glow; i > 0.0; i -= 0.020 )
            {
                llSetPrimitiveParams([PRIM_GLOW, ALL_SIDES, i]);
                //llSleep(1.0);
            }
            llSetPrimitiveParams([PRIM_GLOW, ALL_SIDES, 0]); // Turn off glow when step off prim....
            is_on = FALSE;
            llResetScript();
            
        }
    }
}

Edited by Giyua
Link to comment
Share on other sites

You've got the right idea with the sample script you found. It can be as simple as setting the prim to glow in the collision_start event, and removing the glow on collision_end.

However, I've observed that for solid objects, the collision_end will trigger even if the avatar is still standing on top of it. One way around that is to make the object use llVolumeDetect. This make the object phantom, but still raises collision events. We want this because by making it volumeDetect, the avatar will pass through the object and not raise collision_end events prematurely.

Also, I suspect you want to object to glow as long as at least one person still stands on it. For that, we need to set up a variable to keep track of how many people are currently colliding with it. We do this because if two people are colliding with the object, and one moves off it, that will raise a collision_end event and prematurely stop the glow.

Below is a commented demo of one way to do this:

integer count=0; //keep track of how many people currently coliding with object

default
{
    state_entry()
    {
        llVolumeDetect(TRUE);   //makes object intangable, but will still trigger collision events
    }
    
    collision_start(integer num_detected) 
    {
        count += num_detected;    //colision started, so increment counter
        llSetPrimitiveParams([PRIM_GLOW, ALL_SIDES, 1.0]);  //set glow
    }
    
    collision_end(integer num_detected) 
    {
        count -= num_detected;    //colliiosn stopped, decrement counter
        if(count <1)    //if counter is less than 1, assume no one is colliding anymore
        {
            llSetPrimitiveParams([PRIM_GLOW, ALL_SIDES, 0]);	//clear glow
            count = 0;  //reset counter just in case it somehow became negative.
        }
    }
}

 

Edit1: Completely forgot to say, that by making this prim volumeDetect, you'll obviously need a second object to act as the floor to walk upon of there isn't one there already.

Edit2: incrementing and decrementing the counter by num_detected is better as it covers the edge case if multiple people manage to start (or stop) colliding at the exact same time.

Edited by Fenix Eldritch
corrections
  • Like 1
Link to comment
Share on other sites

  • 1 year later...
8 hours ago, Mark Welch said:

What if we have  1 avatar walking and suddenly he goes offline or crashes? the count will continue to be 1. Any way to solve it? ty

An alternate way of approaching this is to llSensorRepeat() for avatars in-range, and then set the glow for the panel under their feet. If you turn off the sensor when nobody's in range, and only turn it on when an avatar collides with the system, it's reasonably efficient. . . . funnily enough it seems the last time I touched the version I made was a year and a day ago. I'd post the script, but it's specific to custom mesh and (retrospect being 20/20) the style is a bit cryptic.

Link to comment
Share on other sites

2 hours ago, Quistess Alpha said:

An alternate way of approaching this is to llSensorRepeat() for avatars in-range, and then set the glow for the panel under their feet. If you turn off the sensor when nobody's in range, and only turn it on when an avatar collides with the system, it's reasonably efficient. . . . funnily enough it seems the last time I touched the version I made was a year and a day ago. I'd post the script, but it's specific to custom mesh and (retrospect being 20/20) the style is a bit cryptic.

Yes and thank you. But i was thinking in something different when i made the question. Lets forget the glow thing and i just want to know how many avatars are coliding with the floor? the variable count would do the think unless people start crashing or going offline, that will not allow the  collision_end event to trigger. Not sure how to solve this problem. Thank you :)

Link to comment
Share on other sites

1 minute ago, Mark Welch said:

Yes and thank you. But i was thinking in something different when i made the question. Lets forget the glow thing and i just want to know how many avatars are coliding with the floor? the variable count would do the think unless people start crashing or going offline, that will not allow the  collision_end event to trigger. Not sure how to solve this problem. Thank you :)

Yes and the solution is the same, you use colision_start to increment the count, colision_end to decrement it, but also use a sensor or llGetAgentList() to 'sanity check' whether the avatars you think are colliding with the prim, are actually still doing so.

Some impromptu testing is showing a collision_end event when the avatar stops moving, even if they are still on the 'floor'. if that weren't the case, this would work:

// N.B. Sensor can only keep track of 16 (or is it 32?) avatars max.
float gSensorRange = 10.0;

list gColliders;
//integer count; // use llGetListLength(gColliders); instead
default
{
    collision_start(integer n)
    {   llSay(0,"Collision.");
        while(~--n)
        {   key collider = llDetectedKey(n);
            if(llGetAgentSize(collider)) // is an avatar
            {   if(-1==llListFindList(gColliders,[collider])) // prevent a (improbable) double-entry.
                {   gColliders+=collider;
                }
            }
        }
        llOwnerSay((string)llGetListLength(gColliders));
        //count = llGetListLength(gColliders);
        llSensorRepeat("","",AGENT,gSensorRange,PI,0.5);
    }
    collision_end(integer n)
    {   while(~--n)
        {   key collider = llDetectedKey(n);
            integer index= llListFindList(gColliders,[collider]);
            if(-1!=index)
            {   gColliders = llDeleteSubList(gColliders,index,index);
            }
        }
        llOwnerSay("End collision: "+(string)llGetListLength(gColliders));
        //count = llGetListLength(gColliders);
    }
    sensor(integer n)
    {   integer found;
        while(~--n)
        {   integer index = llListFindList(gColliders,[llDetectedKey(n)]);
            if(-1!=index)
            {   found = found|(1<<index);
            }
        }
        integer indexCollider = llGetListLength(gColliders);
        if(found!= (1<<indexCollider)-1 )
        {   llInstantMessage(llGetOwner(),"Lost an avatar to logout or teleport."); // debug.
            while(~--indexCollider)
            {   key collider = llList2Key(gColliders,indexCollider);
                if((~found)&(1<<indexCollider))
                {   gColliders = llDeleteSubList(gColliders,indexCollider,indexCollider);
                }
            }
        }
        //count = llGetListLength(gColliders);
    }
    no_sensor()
    {   gColliders = [];
        llSensorRemove();
        // count = 0;
    }
    touch_start(integer total_number)
    {
        llSay(0, "There are "+(string)llGetListLength(gColliders)+" avatar(s) colliding with me." );
    }
}

 

Link to comment
Share on other sites

On 12/30/2023 at 12:06 PM, Quistess Alpha said:

An alternate way of approaching this is to llSensorRepeat() for avatars in-range

No, please don't do that. You'll have a sensor running all the time for each tile, which eats up sim resources.

If you want to see glow when walking on it, visit Oxymoron, the Graves store. They seem to be detecting collision starts, and triggering something, probably a simple animation, to make the tile glow and then fade out.

  • Like 1
Link to comment
Share on other sites

13 minutes ago, animats said:

No, please don't do that. You'll have a sensor running all the time for each tile, which eats up sim resources.

you only need one sensor for the whole system of tiles, and you can turn the sensor off when it detects nothing, only turn it on after the collision_start event detects an avatar.

14 minutes ago, animats said:

triggering something, probably a simple animation, to make the tile glow and then fade out.

That's actually a good idea, using texture animation to do the fade in/out. It might be a bit of a pain to control though.

Edited by Quistess Alpha
  • Thanks 1
Link to comment
Share on other sites

I'll bet the desired effect is actually emissivity, possibly combined with glow. If fading-in isn't important, just toggling PRIM_FULLBRIGHT might work, otherwise assuming an ALM-capable viewer, a non-looping animation of a PRIM_ALPHA_MODE_EMISSIVE texture (or at this point, heck, a PRIM_GLTF_EMISSIVE texture). But for gradual fading-in on non-ALM viewers, never mind, glow is as close as it gets.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I tried it with 64 2-meter tiles and a root prim under them all, but i think this code only works for one agent at a time?

anyhoo, mebbe someone can use it ...

integer old;
integer new;
default
{
    state_entry()
    {   llSetLinkPrimitiveParamsFast( LINK_ALL_OTHERS,
          [ PRIM_COLOR, ALL_SIDES, <0.0, 0.0, 0.0>, 1.0,
            PRIM_GLOW,ALL_SIDES,0.0
          ]);       
    }
    collision(integer num)
    { 
       new =  llDetectedLinkNumber(0);      
       if( new != 1)
       {
           if(new != old)
           {  llSetLinkPrimitiveParamsFast( new,
              [ PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 1.0,
                PRIM_GLOW,ALL_SIDES,0.1]);
                 
               llSetLinkPrimitiveParamsFast( old,
              [ PRIM_COLOR, ALL_SIDES, <0.0, 0.0, 0.0>, 1.0,
                PRIM_GLOW,ALL_SIDES,0.0]);
              old = new;                         
           }   
        } 
        llSensorRepeat("", "", AGENT_BY_LEGACY_NAME, 8.0, PI, 0.2);            
    }  
    no_sensor() 
    {  llSetLinkPrimitiveParamsFast( LINK_ALL_OTHERS,
          [ PRIM_COLOR, ALL_SIDES, <0.0, 0.0, 0.0>, 1.0,
            PRIM_GLOW,ALL_SIDES,0.0
          ]);
       llSensorRemove();
       old = 0;
    }   
}

 

Edited by Xiija
Link to comment
Share on other sites

this is an interesting problem given the issues of collision and collision_end events not firing in all cases. Events throttled which I think has something to do with objects/agents colliding the sim server to pieces

a way it could be done is to check for agents in proximity to the link on being triggered by collision_start

some p-code

// this is p-code
// has been written off the top of my head
// other than having it compile without error
// i have not tested it at all
// and is pretty brutal p-code tbf, tho it does show the necessary logic


float LINK_RADIUS = 0.5;   // link is active when agent has collided with link prim and is still within the link radius
float TIMER_PERIOD = 2.0;  // period between timer scans

                   // not active    active
list LINK_COLORS = [<1.0, 1.0, 1.0>, <1.0, 0.0, 0.0>];

list collides;

paint()
{
    integer idx = llGetListLength(collides) - 2;
    while (idx > -1)
    {
        integer link = llList2Integer(collides, idx);
        key agent =  llList2Key(collides, idx+1);
        
        vector link_pos = llList2Vector(llGetLinkPrimitiveParams(link, [PRIM_POSITION]), 0);
        vector agent_pos = llList2Vector(llGetObjectDetails(agent, [OBJECT_POS]), 0);
        integer link_active = (llVecDist(link_pos, agent_pos) <= LINK_RADIUS); 
        
        // do lookahead to see if more than one avatar on link
        integer i = idx - 2;
        integer continue = TRUE;
        while ((i > -1) & continue)
        {
            continue = (llList2Integer(collides, i) == link);
            if (continue)
            {
		agent = llList2Key(collides, i+1);
                agent_pos = llList2Vector(llGetObjectDetails(agent, [OBJECT_POS]), 0);
                if (llVecDist(link_pos, agent_pos) <= LINK_RADIUS)
                    link_active = TRUE;
                idx -= 2;
            }
            i -= 2;
        }
        
        // paint link
        llSetLinkColor(link, llList2Vector(LINK_COLORS, link_active), ALL_SIDES);     
               
        if (!link_active)
            collides = llDeleteSubList(collides, idx, idx+1);
        idx -= 2;
    }
    llSetTimerEvent((collides != []) * TIMER_PERIOD); 
}            

default
{
    state_entry()
    {
        llSetColor(llList2Vector(LINK_COLORS, 0), ALL_SIDES);    
    }
    
    collision_start(integer detected)
    {
        // add all links and agents to collides list
        while (~--detected)
            collides += [llDetectedLinkNumber(detected), llDetectedKey(detected)];
            
        // sort by link numbers for paint 
        collides = llListSort(collides, 2, TRUE);       
        paint();
    }
       
    timer()
    {
        paint();
    }
}

 

Edited by elleevelyn
logic err
  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 125 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...