Jump to content

How to make objects in a link set to move independently ?


chrixbed
 Share

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

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

Recommended Posts

I have an object with like 100 links and is attached to an avatar. I want to make a kind of explosion by having all objects individually goes away on a random path and then come back to their original position.

I try to use llSetKeyframedMotion() in each individual linked object but that only work for the root Prim and everything moves together.

So here is my idea:

  1. From the root prim; save all UUID of the link set;
  2. Apply llBreakAllLinks() to free each link;
  3. From each individual object, apply a llSetKeyframedMotion with PING_PONG motion for each object with a random path (this action is called from a llisten() originate from the root prim);
  4. Stop the llSetKeyframedMotion after the path is completed;
  5. From the root link; re-link all objects with llCreateLink() using the UUID previously saved;

Is that making any sense or is there a better (easier) way to do that ?

Note: I'm a bit concerned about the number of llisten() I need to turn on to apply the llSetKeyframedMotion.

Any help will be greatly appreciated, thanks!

 

Link to comment
Share on other sites

You could use a prim animator, and it might accomplish what you are looking to do.

There may be another way to do it that might be more realistic, but I'm not sure how wise it would be to go down this path. Basically it involves rezzing a copy of the item to explode, and having it set temp rez and physical. Then a script inside it would make sure it is physical, and temp rez, and unlink it. The act of unlinking a physical object can make for a nice explosion, especially if the prims overlap slightly. It does require that the owner grant permission to the object before it can unlink itself. Lots of testing would be needed to make sure you aren't making a litter bomb.

I haven't tested the scripted form of this, only the manual version of doing this: Selecting an old style house made of prims, setting it temp-rez and physical, and then clicking unlink..... BOOM!

Link to comment
Share on other sites

If all you want is an explosion, look into the particle system. The movement will be better, and the complexity will be lower.

If you try to manipulate 100 objects that way, things won't happen all at once, and you'll probably slow down the sim for a few seconds.

Look on Marketplace under "Weapons".

Link to comment
Share on other sites

1 minute ago, animats said:

If all you want is an explosion, look into the particle system. The movement will be better, and the complexity will be lower.

If you try to manipulate 100 objects that way, things won't happen all at once, and you'll probably slow down the sim for a few seconds.

Look on Marketplace under "Weapons".

Thanks for the suggestion and yes particle system are great for explosion. But I want to explore something different with PRIM explosion. Ideally I would like to be able to construct and deconstruct structure with multiple prim effect.

Link to comment
Share on other sites

1 hour ago, Phate Shepherd said:

You could use a prim animator, and it might accomplish what you are looking to do.

There may be another way to do it that might be more realistic, but I'm not sure how wise it would be to go down this path. Basically it involves rezzing a copy of the item to explode, and having it set temp rez and physical. Then a script inside it would make sure it is physical, and temp rez, and unlink it. The act of unlinking a physical object can make for a nice explosion, especially if the prims overlap slightly. It does require that the owner grant permission to the object before it can unlink itself. Lots of testing would be needed to make sure you aren't making a litter bomb.

I haven't tested the scripted form of this, only the manual version of doing this: Selecting an old style house made of prims, setting it temp-rez and physical, and then clicking unlink..... BOOM!

Using the trick to set the list of object as physical, unlink it and use small overlap position between object to generate a motion for explosion seem to be an interesting way.

note: is https://www.outworldz.com/cgi/freescripts.plx?ID=52  the script you referring for prim animator?

Link to comment
Share on other sites

There are many factors in your design that make this pretty unfeasible.

  • The fact that it's an attachment means you can't use physics or KFM. You would have to rez a copy of the object  first.
    • If you rezzed a copy and wanted to use KFM, you'd need a script in each prim (100 in this case), which is just grossly excessive and could be considered griefing the sim.
    • If you rezzed a copy and wanted to use physics, you'd have no control over the movement of the individual prims, and no way to make them return smoothly.
  • The fact that you have so many individual links means you're either going to...
    • Have a really good, generic script that can parametrically move all prims with their own pattern, or
    • Have to write an overly complex, massive set of data to determine where each link will go.

What I mean by "generic script" and "parametric" is to basically use something like Bezier curves for your links to follow. You would (perhaps randomly) define some points around the object for each individual link, for example a 4-point curve for 100 links would mean a list with 400 vectors, or 200-300 if you assume that the beginning and end are the same point. Then you would have a loop/timer to calculate the new positions of all 100 links at once (based on current time), then apply them with llSetLinkPrimitiveParamsFast.

This could be done in a pretty short single script, and it would allow a smooth "break-apart-and-expand-before-returning" motion for each individual link simultaneously.

But short doesn't mean simple, and you'd have to be slightly concerned with memory use.

Edited by Wulfie Reanimator
  • Like 1
Link to comment
Share on other sites

51 minutes ago, Wulfie Reanimator said:

There are many factors in your design that make this pretty unfeasible.

  • The fact that it's an attachment means you can't use physics or KFM. You would have to rez a copy of the object  first.
    • If you rezzed a copy and wanted to use KFM, you'd need a script in each prim (100 in this case), which is just grossly excessive and could be considered griefing the sim.
    • If you rezzed a copy and wanted to use physics, you'd have no control over the movement of the individual prims, and no way to make them return smoothly.
  • The fact that you have so many individual links means you're either going to...
    • Have a really good, generic script that can parametrically move all prims with their own pattern, or
    • Have to write an overly complex, massive set of data to determine where each link will go.

What I mean by "generic script" and "parametric" is to basically use something like Bezier curves for your links to follow. You would (perhaps randomly) define some points around the object for each individual link, for example a 4-point curve for 100 links would mean a list with 400 vectors, or 200-300 if you assume that the beginning and end are the same point. Then you would have a loop/timer to calculate the new positions of all 100 links at once (based on current time), then apply them with llSetLinkPrimitiveParamsFast.

This could be done in a pretty short single script, and it would allow a smooth "break-apart-and-expand-before-returning" motion for each individual link simultaneously.

But short doesn't mean simple, and you'd have to be slightly concerned with memory use.

Yes you are right Wulfie about having a generic script that can parametrically calculate a Bezier curves to apply to all the individual prim. I start a short demo to frame the explosion of the link set using llMoveToTarget for now. Next step will be to apply KFM and Bezier and check memory usage as you suggest 🙂

Let me know if you have some insight!

 

here is the code I use: 

// Script to put in every individual objects and than link all those 100 objects together. Name the link set "BoomObjects" and put it into Rezzer Inventory
integer listen_handle;
default
{
    state_entry()
    {
        listen_handle = llListen(-50, "", "", "");
    }

 listen( integer channel, string name, key id, string message )
    {
        if (message == "die"){
            llListenRemove(listen_handle);
            llDie();
        }
        
        if (message == "boom"){

            // This part can be eventually replaced by KLM & Bezier
            llSetStatus(STATUS_PHYSICS, TRUE); // Set the object physical
            llMoveToTarget(llGetPos() + <0.0,0.0,10.0>, 1.0); // Move to a point 10 meters above the present position
            llSetPhysicsMaterial( GRAVITY_MULTIPLIER, -0.5 ,0.0, 0.0, 0.0 );
            llSetPhysicsMaterial( GRAVITY_MULTIPLIER, 1.0 ,0.0, 0.0, 0.0 );

            llSleep(5);
            llResetScript();
        }
    }

}

 

// Script to put in every individual objects and than link all those 100 objects together. Name the link set "BoomObjects" and put it into Rezzer Inventory
integer listen_handle;
default
{
    state_entry()
    {
        listen_handle = llListen(-50, "", "", "");
    }

 listen( integer channel, string name, key id, string message )
    {
        if (message == "die"){
            llListenRemove(listen_handle);
            llDie();
        }
        
        if (message == "boom"){

            // This part can be eventually replaced by KLM & Bezier
            llSetStatus(STATUS_PHYSICS, TRUE); // Set the object physical
            llMoveToTarget(llGetPos() + <0.0,0.0,10.0>, 1.0); // Move to a point 10 meters above the present position
            llSetPhysicsMaterial( GRAVITY_MULTIPLIER, -0.5 ,0.0, 0.0, 0.0 );
            llSetPhysicsMaterial( GRAVITY_MULTIPLIER, 1.0 ,0.0, 0.0, 0.0 );

            llSleep(5);
            llResetScript();
        }
    }

}

 

 

Link to comment
Share on other sites

7 hours ago, chrixbed said:

I have an object with like 100 links and is attached to an avatar.

So here is my idea:

  1. Apply llBreakAllLinks() to free each link;

we can't break/unlink the prims of an attachment while it is being worn

for an attachment we have to move each linked prim while it remains linked

  • Like 1
Link to comment
Share on other sites

1 rez a copy of your object and make attachment invisible
2 all links store position/rotation
3 make the physical explosion thing
4 each part moves and rotates back into stored position (KFM) but that will look different than the explosion - if the explosion uses physics.
5 each part deletes itself and the attachment becomes visible 

Don't move while this happens so the attachment stays in place. (Stand still animation required)

2500 or more listens - triggered at the same time will shatter script execution a bit. 100 listens are nothing. I tested that on an estate sim. Mainland sims may be weaker.
100 physical objects colliding will cause a small peak in computing time.
So if we have one of this objects and they are not triggered 24/7 it's no resource problem.
You need 50 LI free to rez such an object. (for convex prims)
 

Link to comment
Share on other sites

9 hours ago, Mollymews said:

we can't break/unlink the prims of an attachment while it is being worn

for an attachment we have to move each linked prim while it remains linked

Your right, I discover that, so now I'm thinking to rez from attachment with an extra object on the side that will deal with the link/unlink and explosion effect. Is that make sense ?

Link to comment
Share on other sites

7 hours ago, Nova Convair said:

1 rez a copy of your object and make attachment invisible
2 all links store position/rotation
3 make the physical explosion thing
4 each part moves and rotates back into stored position (KFM) but that will look different than the explosion - if the explosion uses physics.
5 each part deletes itself and the attachment becomes visible 

That a very good workflow. that gave me hope I can do that object exploding thing 🙂

Link to comment
Share on other sites

7 hours ago, Nova Convair said:

2500 or more listens - triggered at the same time will shatter script execution a bit. 100 listens are nothing. I tested that on an estate sim. Mainland sims may be weaker.
100 physical objects colliding will cause a small peak in computing time.
So if we have one of this objects and they are not triggered 24/7 it's no resource problem.
You need 50 LI free to rez such an object. (for convex prims)

That super good to know, I'm always afraid to use to many listen state. Do you think I consider a max of 2500 listen overall from all object in a SIM as a good gage ?

Link to comment
Share on other sites

8 hours ago, Nova Convair said:

100 listens are nothing

100 listens is whatever. A single script can have 65 listens.

100 scripts however... a different story.

8ed441ed7c.pngd26a99d547.png

Note how basically everything was halted when the object was rezzed. The object isn't even physical. All 100 scripts were identical copies of the same script and no events were triggered in them during the rez. Still, Physics FPS drops below 1. Spare Time drops from 16ms to 0ms. Everything displayed in the Time tab drops to nothing. The sim will appear frozen, not unlike when an entire avatar enter the sim. Everything just stops.

No effect is worth that cost and I hope you'll develop in a sim with no other people.

Link to comment
Share on other sites

3 minutes ago, Wulfie Reanimator said:

Note how basically everything was halted when the object was rezzed. The object isn't even physical. All 100 scripts were identical copies of the same script and no events were triggered in them during the rez. Still, Physics FPS drops below 1. Spare Time drops from 16ms to 0ms. Everything displayed in the Time tab drops to nothing. The sim will appear frozen, not unlike when an entire avatar enter the sim. Everything just stops.

No effect is worth that cost and I hope you'll develop in a sim with no other people.

Wow that a killing; multiple script seem to be the issue here. Seem a bit crazy but I think there is a way to blow out multiple object with limited SIM impact... my quest is not over yet 😛

Link to comment
Share on other sites

1 hour ago, chrixbed said:

Do you think I consider a max of 2500 listen overall from all object in a SIM as a good gage ?

What I did is: I placed 100 objects with 10 listening scripts each - thats 1000 listeners and 1000 scripts, same channel. Then I placed a sender that sent 1000 messages of about 40 character length. The listeners did a little processing and counting. So thats 1 million events. Takes about a minute since one listener received about 15 messages per second while the sender cound sent 1000 messages in maybe 5 seconds. (The sim buffers the messages so none got lost)

Tried that in different numbers up to 4000 listeners.

4000 is a bit too much. It takes 1-2 minutes until all processing queues got worked off.

However. Every listening script causes a base load and I would not recomment to waste resources by running 1000 listeners all the time. Except it's your sim and you have no tenants.

Short sim shattering actions will most probably not break anything. (Never encountered trouble when testing)

Edited by Nova Convair
Link to comment
Share on other sites

2 minutes ago, Nova Convair said:

What I did is: I placed 100 objects with 10 listening scripts each - thats 1000 listeners and 1000 scripts, same channel. Then I placed a sender that sent 1000 messages of about 40 character length. The listeners did a little processing and counting. So thats 1 million events. Takes about a minute since one listener received about 15 messages per second while the sender cound sent 1000 messages in maybe 5 seconds. (The sim buffers the messages so none got lost)

Very bold and interesting test! Since I'm making kind of live machinima on empty SIM, all my effect are temporary. So I'm not too concern to blow out resource for little visual burst which create a "wow" temporary effect.

 

Thanks for those resource cues, very helpful !

Link to comment
Share on other sites

20 minutes ago, Wulfie Reanimator said:

Everything just stops.

I just made an object of 100 prims with 1 listening script in each prim.

I don't see any effect when i rez one. I rezzed a few left and right while i was walking. Avatar was put back a abit on every rez. (rubberband effect) So the sim was busy for less than 0.1 sec on each rez.

I still see no problem to rez 100 prims with 100 scripts.

Since I can only link 256 prims I made a 100 prim object with 1000 listening scripts. Rezzing that while walking gives a rubberband effect of over 10m and takes a few seconds. So that is sim shattering. 😁

  • Like 1
Link to comment
Share on other sites

2 hours ago, Nova Convair said:

I still see no problem to rez 100 prims with 100 scripts.

100 prim with 100 script works well for me too, so that a good news!

In term of explosion, I try to go to an easy path now and just add like 3 giant sphere to go through the group of prim to make things explode with the following physique:

llSetStatus(STATUS_PHANTOM, FALSE); // Set the object physical
llSetStatus(STATUS_PHYSICS, TRUE); // Set the object physical
llSetPhysicsMaterial(GRAVITY_MULTIPLIER | RESTITUTION | FRICTION | DENSITY, 1,0.2,0.2,100.0);
llMoveToTarget(llGetPos() + <0.0,0.0,30.0>, 0.1); // try to move the big sphere to kick the groups of prim to explode

The 3 spheres are a bit too slow to react and do a good explosion job, any advice to make this better ?

 

 

 

Link to comment
Share on other sites

On 10/12/2020 at 7:24 AM, Wulfie Reanimator said:

What I mean by "generic script" and "parametric" is to basically use something like Bezier curves for your links to follow. You would (perhaps randomly) define some points around the object for each individual link, for example a 4-point curve for 100 links would mean a list with 400 vectors, or 200-300 if you assume that the beginning and end are the same point. Then you would have a loop/timer to calculate the new positions of all 100 links at once (based on current time), then apply them with llSetLinkPrimitiveParamsFast.

This could be done in a pretty short single script, and it would allow a smooth "break-apart-and-expand-before-returning" motion for each individual link simultaneously.

But short doesn't mean simple, and you'd have to be slightly concerned with memory use.

Re: Myself

Here's how to interpolate a position according to a cubic curve (4 points).

vector cubic_curve(float t, list points)
{
    float tt = t * t;
    float ttt = tt * t;
    float u = 1 - t;
    float uu = u * u;
    float uuu = uu * u;

    vector p0 = llList2Vector(points, 0);
    vector p1 = llList2Vector(points, 1);
    vector p2 = llList2Vector(points, 2);
    vector p3 = llList2Vector(points, 3);

    return (uuu * p0) + (3 * uu * t * p1) + (3 * u * tt * p2) + (ttt * p3);
}

This is what it looks like with the start and end at the same point.

This is what it looks like with randomly-generated points for multiple linked prims moving at the same time.

Here's the full script. It will work for as many links as the linkset has. 2, 5, 50, 100, 250, no problem. (Well, besides performance...)

vector cubic_curve(float t, list points)
{
    float tt = t * t;
    float ttt = tt * t;
    float u = 1 - t;
    float uu = u * u;
    float uuu = uu * u;

    vector p0 = llList2Vector(points, 0);
    vector p1 = llList2Vector(points, 1);
    vector p2 = llList2Vector(points, 2);
    vector p3 = llList2Vector(points, 3);

    return (uuu * p0) + (3 * uu * t * p1) + (3 * u * tt * p2) + (ttt * p3);
}

vector get_vector(integer link, integer type)
{
    list data = llGetLinkPrimitiveParams(link, (list)type);
    return llList2Vector(data, 0);
}

float radius = 7;
vector radius_by_2;

default
{
    state_entry()
    {
        // Set stuff up
        radius_by_2 = <radius/2, radius/2, radius/2>;
        list points = [];

        // Generate random points for each link besides the root.
        integer link = 2;
        integer prims = llGetNumberOfPrims();
        while (link <= prims)
        {
            llSetLinkPrimitiveParamsFast(link, [PRIM_TEXT, (string)["link", link], <1,1,1>, 1]);
            vector p = get_vector(link, PRIM_POS_LOCAL);

            points += p; // start
            points += <llFrand(radius), llFrand(radius), llFrand(radius)> - radius_by_2;
            points += <llFrand(radius), llFrand(radius), llFrand(radius)> - radius_by_2;
            points += p; // end
            ++link;
        }

        // Start updating link positions.
        while (TRUE)
        {
            // Get time and adjust its speed
            float t = llGetTime() * 0.2;

            // And make sure we stay in the 0:1 range.
            if (t > 1) t = 1;

            // This list will contain all of the PrimParams we'll apply to each prim.
            list params = [];

            link = 2;
            while (link <= prims)
            {
                // Get the 4 points that belong to the current link.
                integer index = (link - 2) * 4;
                list stride = llList2ListStrided(points, index, index + 3, 0);

                // Calculate its position based on current time.
                params += [PRIM_LINK_TARGET, link, PRIM_POS_LOCAL, cubic_curve(t, stride)];
                ++link;
            }

            // Apply all of the positions at once.
            llSetLinkPrimitiveParamsFast(1, params);
            llSetText((string)["Time: ", t], <1,1,1>, 1);

            if (t >= 1) llResetTime();
        }
    }
}

That's about 40 significant lines of code.

Edited by Wulfie Reanimator
  • Like 3
Link to comment
Share on other sites

On 10/12/2020 at 1:48 AM, chrixbed said:

I have an object with like 100 links and is attached to an avatar. I want to make a kind of explosion by having all objects individually goes away on a random path and then come back to their original position.

 

On 10/12/2020 at 1:48 AM, chrixbed said:

Apply llBreakAllLinks() to free each link;

Can't break links on attachments.

Link to comment
Share on other sites

13 hours ago, Wulfie Reanimator said:

Here's the full script. It will work for as many links as the linkset has. 2, 5, 50, 100, 250, no problem. (Well, besides performance...)

Wulfie, I just test it and OMG, that work so well !! This a very good example on how to use Bezier curve on multiple link set, wow!

 

  • Like 1
Link to comment
Share on other sites

  • 2 years later...
On 10/13/2020 at 2:44 AM, Wulfie Reanimator said:

0

vector cubic_curve(float t, list points)
{
    float tt = t * t;
    float ttt = tt * t;
    float u = 1 - t;
    float uu = u * u;
    float uuu = uu * u;

    vector p0 = llList2Vector(points, 0);
    vector p1 = llList2Vector(points, 1);
    vector p2 = llList2Vector(points, 2);
    vector p3 = llList2Vector(points, 3);

    return (uuu * p0) + (3 * uu * t * p1) + (3 * u * tt * p2) + (ttt * p3);
}

vector get_vector(integer link, integer type)
{
    list data = llGetLinkPrimitiveParams(link, (list)type);
    return llList2Vector(data, 0);
}

float radius = 7;
vector radius_by_2;

default
{
    state_entry()
    {
        // Set stuff up
        radius_by_2 = <radius/2, radius/2, radius/2>;
        list points = [];

        // Generate random points for each link besides the root.
        integer link = 2;
        integer prims = llGetNumberOfPrims();
        while (link <= prims)
        {
            llSetLinkPrimitiveParamsFast(link, [PRIM_TEXT, (string)["link", link], <1,1,1>, 1]);
            vector p = get_vector(link, PRIM_POS_LOCAL);

            points += p; // start
            points += <llFrand(radius), llFrand(radius), llFrand(radius)> - radius_by_2;
            points += <llFrand(radius), llFrand(radius), llFrand(radius)> - radius_by_2;
            points += p; // end
            ++link;
        }

        // Start updating link positions.
        while (TRUE)
        {
            // Get time and adjust its speed
            float t = llGetTime() * 0.2;

            // And make sure we stay in the 0:1 range.
            if (t > 1) t = 1;

            // This list will contain all of the PrimParams we'll apply to each prim.
            list params = [];

            link = 2;
            while (link <= prims)
            {
                // Get the 4 points that belong to the current link.
                integer index = (link - 2) * 4;
                list stride = llList2ListStrided(points, index, index + 3, 0);

                // Calculate its position based on current time.
                params += [PRIM_LINK_TARGET, link, PRIM_POS_LOCAL, cubic_curve(t, stride)];
                ++link;
            }

            // Apply all of the positions at once.
            llSetLinkPrimitiveParamsFast(1, params);
            llSetText((string)["Time: ", t], <1,1,1>, 1);

            if (t >= 1) llResetTime();
        }
    }
}

That's about 40 significant lines of code.

Edited October 13, 2020 by Wulfie Reanimator
Like

Kyrah Abattoir
  • Confused 1
Link to comment
Share on other sites

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