llSetVehicleFlags(); VEHICLE_FLAG_CAMERA_DECOUPLED does not work and the reason why
tracked
Nexii Malthus
So in a previous feedback it was outlined that camera decoupled requires the steer or bank flags as well to work (https://feedback.secondlife.com/scripting-bugs/p/llsetvehicleflags-vehicle-flag-camera-decoupled-does-not-work)
It was also mentioned that camera decoupled is sent in an object update message to the client.
However there is a bug that llSetVehicleFlags does not trigger a full object update message.
So, if you have an efficient script that minimises what it needs to set without triggering an object update and the client still thinks the object doesn't have camera decoupling enabled then the camera decoupling doesn't work!
The current hacky workaround is to use something that can force a full update, such as setting hover text.
The real issue is that setting or removing the camera decoupling flag should trigger the relevant network update to pass the information to the client.
I was frequently reproducing this issue on a vehicle I was working on trying to figure out what the issue was but it became reproducible once I knew the trick was related to triggering a full object update.
Log In
Maestro Linden
tracked
Hi Nexii Malthus, nice find. I modified the script in the other canny issue to not generate constant object updates, and instead toggle VEHICLE_FLAG_CAMERA_DECOUPLED based on chat commands from the agent. I do see that when the VEHICLE_FLAG_CAMERA_DECOUPLED is set or unset in isolation, there is no change in the vehicle behavior until a full object update is triggered.
My repro is:
- Rez a box
- Save the script below in the box
- Enable "Show Updates To Objects" in the viewer
- Sit on the box, and enter mouselook mode. Note that VEHICLE_FLAG_CAMERA_DECOUPLED is initially enabled (the vehicle is stable when looking in a certain horizontal direction)
- Say "coupled" in chat, which will cause the script to removethe VEHICLE_FLAG_CAMERA_DECOUPLED flag, but not trigger any additional updates
- Note if vehicle behavior changes when moving the mouselook camera
- Say "update" in chat, to trigger a full object update (floating text) on the vehicle
- Note if vehicle behavior changes when moving the mouselook camera
- Say "coupled" in chat, which will cause the script to setthe VEHICLE_FLAG_CAMERA_DECOUPLED flag, but not trigger any additional updates
- Note if vehicle behavior changes when moving the mouselook camera
- Say "update" in chat, to trigger a full object update (floating text) on the vehicle
- Note if vehicle behavior changes when moving the mouselook camera
Expected results:
- Calling llSetVehicleFlags and llRemoveVehicleFlags with the VEHICLE_FLAG_CAMERA_DECOUPLED parameter should have an immediate effect, without needing to trigger another object update.
- In general, steering should be pretty stable when VEHICLE_FLAG_CAMERA_DECOUPLED is enabled, and pretty unstable otherwise.
Actual results:
- Toggling VEHICLE_FLAG_CAMERA_DECOUPLED on/off has no effect until a full object update is triggered via the "update" command's floating text update.
key avatar;
default
{
state_entry()
{
llSay(0, "let's go");
llSetScale(<4,2.5,1>);
llSitTarget(<-1,0.05,0>, ZERO_ROTATION); // have the agent sit back a bit so we can read floating text
llSetVehicleType(4);
// most friction for left-right, least for up-down
llSetVehicleVectorParam( VEHICLE_LINEAR_FRICTION_TIMESCALE, <2, 2, 2> );
// no angular friction
llSetVehicleVectorParam( VEHICLE_ANGULAR_FRICTION_TIMESCALE, <2, 2, 2 >);
// linear motor wins after about a second, decays after about a minute
llSetVehicleVectorParam( VEHICLE_LINEAR_MOTOR_DIRECTION, <0, 0, 0> );
llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_TIMESCALE, 1 );
llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 60 );
// agular motor wins after a second, decays in less time than that
llSetVehicleVectorParam( VEHICLE_ANGULAR_MOTOR_DIRECTION, <0, 0, 0> );
llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, 1 );
llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.8 );
// no hover
llSetVehicleFloatParam( VEHICLE_HOVER_HEIGHT, 0 );
llSetVehicleFloatParam( VEHICLE_HOVER_EFFICIENCY, 0 );
llSetVehicleFloatParam( VEHICLE_HOVER_TIMESCALE, 10 );
llSetVehicleFloatParam( VEHICLE_BUOYANCY, 1 );
// maximum linear deflection with timescale of 2 seconds
llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1 );
llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 2 );
// no angular deflection
llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0 );
llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 10 );
// critically damped vertical attractor
llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0 );
llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 10 );
// weak negative critically damped banking
llSetVehicleFloatParam( VEHICLE_BANKING_EFFICIENCY, 0.0 );
// llSetVehicleFloatParam( VEHICLE_BANKING_MIX, 1 );
llSetVehicleFloatParam( VEHICLE_BANKING_TIMESCALE, 1000 );
// default rotation of local frame
llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME, <0, 0, 0, 0> );
// remove these flags
llRemoveVehicleFlags(VEHICLE_FLAG_LIMIT_MOTOR_UP | VEHICLE_FLAG_NO_DEFLECTION_UP | VEHICLE_FLAG_LIMIT_ROLL_ONLY | VEHICLE_FLAG_MOUSELOOK_STEER | VEHICLE_FLAG_CAMERA_DECOUPLED);
integer flags = VEHICLE_FLAG_MOUSELOOK_STEER | VEHICLE_FLAG_CAMERA_DECOUPLED;
llSetVehicleFlags(flags);
llOwnerSay("VEHICLE_FLAG_CAMERA_DECOUPLED flag is currently set");
llListen(0, "", llGetOwner(), "");
}
listen(integer channel, string name, key id, string msg)
{
msg = llStringTrim(msg, STRING_TRIM);
if(msg == "coupled")
{
llOwnerSay("removing the VEHICLE_FLAG_CAMERA_DECOUPLED vehicle flag.");
llRemoveVehicleFlags(VEHICLE_FLAG_CAMERA_DECOUPLED);
}
else if(msg == "decoupled")
{
llOwnerSay("adding the VEHICLE_FLAG_CAMERA_DECOUPLED vehicle flag.");
llSetVehicleFlags(VEHICLE_FLAG_CAMERA_DECOUPLED);
}
else if(msg == "update")
{
llSetText(llGetTimestamp(), <1,1,1>, 1);
}
}
changed(integer change)
{
if(change & CHANGED_LINK)
{
key agent = llAvatarOnSitTarget();
if (agent)
{
llRequestPermissions(agent, PERMISSION_TAKE_CONTROLS | PERMISSION_TRACK_CAMERA);
llSetStatus(STATUS_PHYSICS, TRUE);
llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, TRUE);
}
}
}
run_time_permissions(integer perm)
{
if (perm)
{
//llStartAnimation("SpeedbuildPose1");
llTakeControls (CONTROL_FWD | CONTROL_BACK | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_UP | CONTROL_DOWN, TRUE, FALSE);
}
}
control(key id, integer held, integer change)
{
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, <5.0, 5.0, 5.0>);
}
}