llSetLinkPrimitiveParamsFast is slower than expected
- Saros Eclipse
- Posts: 9
- Joined: Tue Aug 09, 2016 11:46 pm
- Location: Lynnwood, WA
- Has thanked: 1 time
- Been thanked: 4 times
llSetLinkPrimitiveParamsFast is slower than expected
Hi, I'm new to Kitely but not new to scripting. I have an object rotation script that uses llSetLinkPrimitiveParamsFast, but behaves as if it's sleeping between calls. This is my actual code:
rotation newRotation = llEuler2Rot(<x, y, z> * DEG_TO_RAD);
newRotation = newRotation * base_rot;
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, newRotation]);
I set the timer for 32 updates per second, but I'm only seeing 4 or 5 per second. I would expect that if I were using llSetPrimitiveParams or llSetLinkPrimitiveParams, but I'm using the fast one.
Is this a known problem, or is there a workaround?
Thanks,
Saros
rotation newRotation = llEuler2Rot(<x, y, z> * DEG_TO_RAD);
newRotation = newRotation * base_rot;
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, newRotation]);
I set the timer for 32 updates per second, but I'm only seeing 4 or 5 per second. I would expect that if I were using llSetPrimitiveParams or llSetLinkPrimitiveParams, but I'm using the fast one.
Is this a known problem, or is there a workaround?
Thanks,
Saros
mostly harmless.
- Ilan Tochner
- Posts: 6518
- Joined: Sun Dec 23, 2012 8:44 am
- Has thanked: 4972 times
- Been thanked: 4469 times
- Contact:
Re: llSetLinkPrimitiveParamsFast is slower than expected
Hi Saros,
What is the CPU usage of your world after it has finished starting up? See: https://kitely.atlassian.net/wiki/displ ... erformance
Have you tried a simple test of just moving a cube back and forth with llSetLinkPrimitiveParamsFast and seeing how often that is updated?
What is the CPU usage of your world after it has finished starting up? See: https://kitely.atlassian.net/wiki/displ ... erformance
Have you tried a simple test of just moving a cube back and forth with llSetLinkPrimitiveParamsFast and seeing how often that is updated?
- Saros Eclipse
- Posts: 9
- Joined: Tue Aug 09, 2016 11:46 pm
- Location: Lynnwood, WA
- Has thanked: 1 time
- Been thanked: 4 times
Re: llSetLinkPrimitiveParamsFast is slower than expected
Hi Ilan,
The CPU graph is hugging the line at 0, and so are Packets Received and Packets Resent. Packets Sent is under 10%.
Using Top Scripts in region debug, the top five mover scripts are 5, 5, 5, 4 and 4 ms for a total of 23 ms. The world is brand new (evergreen island model) and this is the first thing I've tried building in it.
There are only a small handful of scripts, some of which are idling watching for movement (which never happens unless the anchor object is dragged). The others are listening for messages shouted by the anchors, and meanwhile animating in the timer() function.
The CPU graph is hugging the line at 0, and so are Packets Received and Packets Resent. Packets Sent is under 10%.
Using Top Scripts in region debug, the top five mover scripts are 5, 5, 5, 4 and 4 ms for a total of 23 ms. The world is brand new (evergreen island model) and this is the first thing I've tried building in it.
There are only a small handful of scripts, some of which are idling watching for movement (which never happens unless the anchor object is dragged). The others are listening for messages shouted by the anchors, and meanwhile animating in the timer() function.
mostly harmless.
- Handy Low
- Posts: 231
- Joined: Fri Nov 08, 2013 3:38 pm
- Location: Yorkshire, England
- Has thanked: 207 times
- Been thanked: 140 times
- Contact:
Re: llSetLinkPrimitiveParamsFast is slower than expected
You mean using llSetTimerEvent? You can only have 0.5s timers in OpenSim, no faster.Saros Eclipse wrote:I set the timer for 32 updates per second
Handy Low
- Saros Eclipse
- Posts: 9
- Joined: Tue Aug 09, 2016 11:46 pm
- Location: Lynnwood, WA
- Has thanked: 1 time
- Been thanked: 4 times
Re: llSetLinkPrimitiveParamsFast is slower than expected
I guess that would do it. Then how can I run any animation that updates faster than two times a second?You mean using llSetTimerEvent? You can only have 0.5s timers in OpenSim, no faster.
mostly harmless.
- Saros Eclipse
- Posts: 9
- Joined: Tue Aug 09, 2016 11:46 pm
- Location: Lynnwood, WA
- Has thanked: 1 time
- Been thanked: 4 times
Re: llSetLinkPrimitiveParamsFast is slower than expected
I've been reading the OS LSL wiki and trying various things that seem like they might help. It doesn't say so explicitly, but I suspect llGetPos(), llGetRot() and llGetPrimitiveParams() should be added to your list of things that cause sleep. I tried replacing these with llGetLinkPrimitiveParams() just to be safe, but it didn't improve things noticeably. It makes the scripts more self consistent though, so I'm keeping it.Ilan Tochner wrote:Have you tried a simple test of just moving a cube back and forth with llSetLinkPrimitiveParamsFast and seeing how often that is updated?
The best I can do is getting the five scripts down to 17-20 ms. The remaining anchor scripts (about a dozen) consume less than 1 ms total.
mostly harmless.
- Saros Eclipse
- Posts: 9
- Joined: Tue Aug 09, 2016 11:46 pm
- Location: Lynnwood, WA
- Has thanked: 1 time
- Been thanked: 4 times
Re: llSetLinkPrimitiveParamsFast is slower than expected
FYI here are my actual scripts. These are a way to attach animated objects to each other hierarchically and animate them synchronously without inter-object communication, using the sim time clock.
Linked Anchor senses when it's been moved, and broadcasts its new position and rotation. This script is put into a child prim, and another linked object will listen for messages from it:
Linked Static simply moves its object to the new position and rotation that it receives in a message from the anchor. It listens for the object according to channel and the name of the anchor child prim:
Linked Driveshaft Rotation is an example of an animation script that repositions itself according to messages from its anchor. The motion is automatically in sync with other animated objects by virtue of using llGetTimeOfDay(), which is the same for every object in the world.
The constants at the top of the script control the object's relative rotation, range of movement, phase offset and time for a complete animation cycle:
Linked Anchor senses when it's been moved, and broadcasts its new position and rotation. This script is put into a child prim, and another linked object will listen for messages from it:
Code: Select all
integer say_chan = -42432;
vector base_pos = <0,0,0>;
rotation base_rot = <0,0,0,0>;
string FormatDecimal(float number, integer precision)
{
float roundingValue = llPow(10, -precision)*0.5;
float rounded;
if (number < 0) rounded = number - roundingValue;
else rounded = number + roundingValue;
if (precision < 1) // Rounding integer value
{
integer intRounding = (integer)llPow(10, -precision);
rounded = (integer)rounded/intRounding*intRounding;
precision = -1; // Don't truncate integer value
}
string strNumber = (string)rounded;
return llGetSubString(strNumber, 0, llSubStringIndex(strNumber, ".") + precision);
}
default
{
state_entry()
{
llSetTimerEvent(1.0);
}
timer()
{
list params = llGetLinkPrimitiveParams( LINK_THIS, [PRIM_POSITION, PRIM_ROTATION]);
vector new_pos = llList2Vector( params, 0 );
rotation new_rot = llList2Rot( params, 1 );
integer go = 0;
if (base_pos != new_pos) {
base_pos = new_pos;
go = 1;
}
if (base_rot != new_rot) {
base_rot = new_rot;
go = 1;
}
if (go) {
vector euler_rot = llRot2Euler(base_rot) * RAD_TO_DEG;
llShout( say_chan, "position " + FormatDecimal(base_pos.x,2) + " " + FormatDecimal(base_pos.y,2) + " " + FormatDecimal(base_pos.z,2) + " rotation " + FormatDecimal(euler_rot.x,2) + " " + FormatDecimal(euler_rot.y,2) + " " + FormatDecimal(euler_rot.z,2));
}
}
}
Code: Select all
string obj_name = "Anchor Pivot";
integer listen_chan = -42432;
integer listen_handle;
default
{
state_entry()
{
listen_handle = llListen( listen_chan, obj_name, "", "" );
}
listen( integer channel, string name, key id, string message )
{
list values = llParseString2List( message, [" "], [] );
if ((llList2String(values,0) == "position") && (llList2String(values,4) == "rotation")) {
vector new_pos = < llList2Float(values,1),
llList2Float(values,2),
llList2Float(values,3) >;
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, new_pos]);
vector new_rot = < llList2Float(values,5),
llList2Float(values,6),
llList2Float(values,7) >;
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, llEuler2Rot(new_rot * DEG_TO_RAD)]);
}
}
}
The constants at the top of the script control the object's relative rotation, range of movement, phase offset and time for a complete animation cycle:
Code: Select all
string obj_name = "Anchor Driveshaft";
integer listen_chan = -42432;
float update_rate = 24.0;
float cycle_time = -24.0;
float range = 8.0;
float x_rotation = 0.0;
float y_rotation = 0.0;
float z_rotation = -106.0;
float offset = 0.0;
rotation base_rot = <0,0,0,0>;
integer listen_handle;
default
{
state_entry()
{
list params = llGetLinkPrimitiveParams( LINK_THIS, [PRIM_ROTATION]);
base_rot = llList2Rot( params, 0 );
listen_handle = llListen( listen_chan, obj_name, "", "" );
llSetTimerEvent(1.0/update_rate);
}
listen( integer channel, string name, key id, string message )
{
list values = llParseString2List( message, [" "], [] );
if ((llList2String(values,0) == "position") && (llList2String(values,4) == "rotation")) {
vector new_pos = < llList2Float(values,1),
llList2Float(values,2),
llList2Float(values,3) >;
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, new_pos]);
vector new_rot = < llList2Float(values,5),
llList2Float(values,6),
llList2Float(values,7) >;
base_rot = llEuler2Rot(new_rot * DEG_TO_RAD);
}
}
timer()
{
float newAngle = llGetTimeOfDay() * 360.0 / cycle_time;
float x = x_rotation;
float y = y_rotation;
float z = z_rotation + newAngle;
rotation newRotation = llEuler2Rot(<x, y, z> * DEG_TO_RAD);
newRotation = newRotation * base_rot;
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, newRotation]);
}
}
mostly harmless.
- Kayaker Magic
- Posts: 354
- Joined: Sun Dec 01, 2013 8:40 am
- Has thanked: 52 times
- Been thanked: 393 times
Re: llSetLinkPrimitiveParamsFast is slower than expected
Try using llSetKeyframedMotion to make your object rotate. You can call it once a second if you need to change the rotation often and let it run between timer events. This uses less server resources than calling llSetLinkPrimitiveParameters 32 times a second.
I use llSetKeyframedMotion for all my non-physical vehicles and critters. I do my own physics calculations once a second (or twice a second for a responsive vehicle like a windsurfer) and have llSetKeyframedMotion interpolate the position and rotation between calculations.
I use llSetKeyframedMotion for all my non-physical vehicles and critters. I do my own physics calculations once a second (or twice a second for a responsive vehicle like a windsurfer) and have llSetKeyframedMotion interpolate the position and rotation between calculations.
- These users thanked the author Kayaker Magic for the post (total 2):
- Saros Eclipse • Ilan Tochner
- Handy Low
- Posts: 231
- Joined: Fri Nov 08, 2013 3:38 pm
- Location: Yorkshire, England
- Has thanked: 207 times
- Been thanked: 140 times
- Contact:
Re: llSetLinkPrimitiveParamsFast is slower than expected
And another solution is to use llTargetOmega, which has the advantage of deferring all the processing to the client.
- These users thanked the author Handy Low for the post:
- Ilan Tochner
Handy Low
- Saros Eclipse
- Posts: 9
- Joined: Tue Aug 09, 2016 11:46 pm
- Location: Lynnwood, WA
- Has thanked: 1 time
- Been thanked: 4 times
Re: llSetLinkPrimitiveParamsFast is slower than expected
I use llTargetOmega for things that don't need to be synchronized. Unfortunately a few of the items need to stay in sync, and the scripts wouldn't sync up unless they were started at the same instant and never interrupted.Handy Low wrote:And another solution is to use llTargetOmega, which has the advantage of deferring all the processing to the client.
mostly harmless.