Difference between revisions of "CameraSynch2"
Jump to navigation
Jump to search
BETLOG Hax (talk | contribs) (New page: ==Hax CameraSynch v1.0.0== Synchronization of multiple avatar cameras. <br> This script initially needs to be dropped individually in numerous prims, which are then linked together. Howeve...) |
m (Changed the <lsl> tag to <source lang="lsl2"> and added line breaks between events to make the code more readable) |
||
(9 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
== | {{LSL Header|ml=*}} | ||
== CameraSynch2 v1.0.0 == | |||
Synchronization of multiple avatar cameras. | Synchronization of multiple avatar cameras. | ||
<br> | <br> | ||
This script initially needs to be dropped individually | This script initially needs to be dropped individually into numerous linked prims. | ||
<br> | |||
However because the script adds a PIN, after its been added once the owner can issue the "update" command to automatically propogate any changes made to the root script into the child prims/scripts. | However because the script adds a PIN, after its been added once the owner can issue the "update" command to automatically propogate any changes made to the root script into the child prims/scripts. | ||
<br> | |||
<br> | |||
TO USE: | |||
<br> | |||
1] Rez a bunch of prims, one for each bum you want to sit on them. | |||
<br> | |||
2] Link them together. | |||
<br> | |||
3] Drop a copy of this script in each prim. | |||
<br> | |||
4] Sit one person on the controller seat, and some persons on the other seats. | |||
<br> | |||
5] Read the spam when you sit down. | |||
<br> | |||
<div style="padding: 0.5em;"> | <div style="padding: 0.5em;"> | ||
< | <source lang="lsl2"> | ||
// | // | ||
// BELOG Hax | // BELOG Hax | ||
// AEST 20071221 0452 [SLT: 20071220 1152] | // AEST 20071221 0452 [SLT: 20071220 1152] | ||
// https://wiki.secondlife.com/wiki/CameraSynch2 | |||
// | // | ||
// VERSION: | // VERSION: | ||
Line 22: | Line 39: | ||
// but theirs was the original..and Nomad is awesome. | // but theirs was the original..and Nomad is awesome. | ||
//========================================================================= | //========================================================================= | ||
// LICENCE | // ---LICENCE START--- | ||
// http://creativecommons.org/licenses/by-sa/3.0/ | |||
// | // ie: Attribution licence: | ||
// | // Give me credit by leaving it in the script I created. | ||
// | // Supply my original script with your modified version. | ||
// | // Refer to the wiki URL from which you copied this script. | ||
// | // https://wiki.secondlife.com/wiki/CameraSynch2 | ||
// ---LICENCE END--- | |||
// | |||
/ | |||
// | |||
// | |||
//========================================================================= | //========================================================================= | ||
// SHARED CONFIGURATION | // SHARED CONFIGURATION | ||
integer gPayloadPIN = 89876847; | integer gPayloadPIN = 89876847; | ||
Line 68: | Line 82: | ||
//---------------------------------- | //---------------------------------- | ||
default | default | ||
{ on_rez(integer start_param) | { | ||
on_rez(integer start_param) | |||
{ llResetScript(); | { llResetScript(); | ||
} | } | ||
state_entry() | state_entry() | ||
{ if (gPayloadPIN) llSetRemoteScriptAccessPin(gPayloadPIN); | { if (gPayloadPIN) llSetRemoteScriptAccessPin(gPayloadPIN); | ||
Line 88: | Line 104: | ||
llListen(gChan, "", llGetOwner(), "update"); | llListen(gChan, "", llGetOwner(), "update"); | ||
} | } | ||
listen(integer channel, string name, key id, string message) | listen(integer channel, string name, key id, string message) | ||
{ integer cc; | { integer cc; | ||
Line 100: | Line 117: | ||
llOwnerSay("OK: Script propogation completed."); | llOwnerSay("OK: Script propogation completed."); | ||
} | } | ||
changed(integer change) | changed(integer change) | ||
{ if (change & CHANGED_LINK) | { if (change & CHANGED_LINK) | ||
Line 115: | Line 133: | ||
} | } | ||
} | } | ||
run_time_permissions(integer perm) | run_time_permissions(integer perm) | ||
{ if(perm & PERMISSION_TAKE_CONTROLS) | { if(perm & PERMISSION_TAKE_CONTROLS) | ||
Line 133: | Line 152: | ||
llUnSit(gCamController); | llUnSit(gCamController); | ||
} | } | ||
timer() | timer() | ||
{ vector camPos = llGetCameraPos(); | { vector camPos = llGetCameraPos(); | ||
Line 148: | Line 168: | ||
//========================================================================= | //========================================================================= | ||
state repeater | state repeater | ||
{ on_rez(integer start_param) | { | ||
on_rez(integer start_param) | |||
{ llResetScript(); | { llResetScript(); | ||
} | } | ||
state_entry() | state_entry() | ||
{ llSetTimerEvent(0.0); | { llSetTimerEvent(0.0); | ||
} | } | ||
changed(integer change) | changed(integer change) | ||
{ if (change & CHANGED_LINK) | { if (change & CHANGED_LINK) | ||
Line 164: | Line 187: | ||
} | } | ||
} | } | ||
run_time_permissions(integer perms) | run_time_permissions(integer perms) | ||
{ if (perms & PERMISSION_CONTROL_CAMERA) | { if (perms & PERMISSION_CONTROL_CAMERA) | ||
Line 182: | Line 206: | ||
} | } | ||
} | } | ||
timer() | timer() | ||
{ if (llGetPermissionsKey()) | { if (llGetPermissionsKey()) | ||
Line 195: | Line 220: | ||
CAMERA_ACTIVE, 1 //1 is active, 0 is inactive | CAMERA_ACTIVE, 1 //1 is active, 0 is inactive | ||
,CAMERA_BEHINDNESS_ANGLE, 0.0 //(0 to 180) degrees | ,CAMERA_BEHINDNESS_ANGLE, 0.0 //(0 to 180) degrees | ||
// | //,CAMERA_BEHINDNESS_LAG, 0.05 //(0 to 3) seconds | ||
,CAMERA_DISTANCE, 0.0 //(0.5 to 10) meters | ,CAMERA_DISTANCE, 0.0 //(0.5 to 10) meters | ||
,CAMERA_FOCUS, pos + llRot2Fwd(rot) //Region-relative | ,CAMERA_FOCUS, pos + llRot2Fwd(rot) //Region-relative | ||
Line 214: | Line 239: | ||
} | } | ||
//========================================================================= | //========================================================================= | ||
</source> | |||
</ | |||
</div> | </div> | ||
{{LSLC|Examples| | {{LSLC|Examples|CameraSynch2}} |
Latest revision as of 14:54, 24 January 2015
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
CameraSynch2 v1.0.0
Synchronization of multiple avatar cameras.
This script initially needs to be dropped individually into numerous linked prims.
However because the script adds a PIN, after its been added once the owner can issue the "update" command to automatically propogate any changes made to the root script into the child prims/scripts.
TO USE:
1] Rez a bunch of prims, one for each bum you want to sit on them.
2] Link them together.
3] Drop a copy of this script in each prim.
4] Sit one person on the controller seat, and some persons on the other seats.
5] Read the spam when you sit down.
//
// BELOG Hax
// AEST 20071221 0452 [SLT: 20071220 1152]
// https://wiki.secondlife.com/wiki/CameraSynch2
//
// VERSION:
// v1.0.0 revised and wikified from my previous: 'CameraSynch v0.3.1'
// Not really well tested, but seems good.
// Timer frequency could do with some moderation... Possibly with dynamic adjustment.
//
// CREDITS:
// Meyermagic Salome and Nomad Padar for
// http://wiki.secondlife.com/wiki/Camera_Sync
// I drew some inspiration from theirs some time after I wrote the first iteration of this script.
// I don't think I actually derived anything from it...
// but theirs was the original..and Nomad is awesome.
//=========================================================================
// ---LICENCE START---
// http://creativecommons.org/licenses/by-sa/3.0/
// ie: Attribution licence:
// Give me credit by leaving it in the script I created.
// Supply my original script with your modified version.
// Refer to the wiki URL from which you copied this script.
// https://wiki.secondlife.com/wiki/CameraSynch2
// ---LICENCE END---
//=========================================================================
// SHARED CONFIGURATION
integer gPayloadPIN = 89876847;
//----------------------------------
// CONFIGURATION
float gFrequency = 0.02;
integer gChan = 0;
//----------------------------------
// CORE CODE - controller
string gCamController = NULL_KEY;
vector gOldCamPos;
rotation gOldCamRot;
string gOldDesc;
integer gTog;
// CORE CODE - spectator
//--------------------------------------
f_camDefault()
{ llSetCameraParams([
CAMERA_ACTIVE, FALSE, //1 is active, 0 is inactive
CAMERA_BEHINDNESS_ANGLE, 10.0, //(0 to 180) degrees
CAMERA_BEHINDNESS_LAG, 0.0, //(0 to 3) seconds
CAMERA_DISTANCE, 3.0, //(0.5 to 10) meters
CAMERA_FOCUS_LAG, 0.1 , //(0 to 3) seconds
CAMERA_FOCUS_LOCKED, FALSE, //(TRUE or FALSE)
CAMERA_FOCUS_THRESHOLD, 1.0, //(0 to 4) meters
CAMERA_PITCH, 0.0, //(-45 to 80) degrees
CAMERA_POSITION_LAG, 0.1, //(0 to 3) seconds
CAMERA_POSITION_LOCKED, FALSE, //(TRUE or FALSE)
CAMERA_POSITION_THRESHOLD, 1.0, //(0 to 4) meters
CAMERA_FOCUS_OFFSET, ZERO_VECTOR //<-10,-10,-10> to <10,10,10> meters
]);
}
//----------------------------------
default
{
on_rez(integer start_param)
{ llResetScript();
}
state_entry()
{ if (gPayloadPIN) llSetRemoteScriptAccessPin(gPayloadPIN);
llSitTarget(<0.2, 0.0, 0.5>, <0.0, 0.0, 0.0, 1.0>);
integer link = llGetLinkNumber();
if (link>1)
{ string name = "Spectator#"+(string)(link-1);
llSetObjectName(name);
llSetColor(<0.0, 1.0, 1.0>, ALL_SIDES);
llSetText(name, <1.0, 1.0, 1.0>, 1.0);
state repeater;
}
llSetColor(<1.0, 1.0, 0.0>, ALL_SIDES);
llSetObjectName(llGetScriptName());
llSetText("CONTROLLER", <1.0, 1.0, 1.0>,1.0);
if (gPayloadPIN)
llListen(gChan, "", llGetOwner(), "update");
}
listen(integer channel, string name, key id, string message)
{ integer cc;
integer c = cc = llGetNumberOfPrims();
llOwnerSay("WAIT: Propogating scripts...");
while(c>1)
{ llSetText("Updating: "+(string)(cc-c+1)+"/"+(string)(cc-1)
, <1.0, 1.0, 1.0>, 1.0);
llRemoteLoadScriptPin(llGetLinkKey(c--), llGetScriptName(), gPayloadPIN, TRUE, 1);
}
llSetText("CONTROLLER", <1.0, 1.0, 1.0>, 1.0);
llOwnerSay("OK: Script propogation completed.");
}
changed(integer change)
{ if (change & CHANGED_LINK)
{ gCamController = llAvatarOnSitTarget();
if (gCamController != NULL_KEY)
{ llRequestPermissions(gCamController
, PERMISSION_TRACK_CAMERA|PERMISSION_TAKE_CONTROLS
);
}
else
{ llSetTimerEvent(0.0);
llSetObjectDesc(gOldDesc);
llResetScript();
}
}
}
run_time_permissions(integer perm)
{ if(perm & PERMISSION_TAKE_CONTROLS)
{ llTakeControls(0| CONTROL_LBUTTON,TRUE, TRUE); //work anywhere
llInstantMessage(llGetPermissionsKey(),
"\nThis device allows the spectator cameras to be controlled by YOU."
+"\nUseful Tips:"
+"\n1] Ensure you are NOT in mouselook."
+"\n2] Spectators cameras track yours with a short delay, and do not move quite as smoothly "
+"as yours does, so go slowly and avoid any sudden or disconcerting movements."
+"\nREMEMBER: If your drawdistance is greater than a spectators, their camera may be left "
+"behind at some point. So if you hear people say 'did we stop moving?' you should move "
+"your camera closer to where you are all sitting."
);
llSetTimerEvent(gFrequency);
}
else //never
llUnSit(gCamController);
}
timer()
{ vector camPos = llGetCameraPos();
rotation camRot = llGetCameraRot();
if (llVecDist(camPos, gOldCamPos) > 0.001
|| llAngleBetween(camRot, gOldCamRot) >= 0.0008)
{ gTog = !gTog;
gOldCamPos = camPos;
gOldCamRot = camRot;
llSetText("RELAYING..",<0.0, (float)gTog, 1.0-gTog>,1.0);
llSetObjectDesc((string)camPos+"#"+(string)camRot);
}
}
}
//=========================================================================
state repeater
{
on_rez(integer start_param)
{ llResetScript();
}
state_entry()
{ llSetTimerEvent(0.0);
}
changed(integer change)
{ if (change & CHANGED_LINK)
{ if (llGetLinkNumber() == 0)
llResetScript();
key av = llAvatarOnSitTarget();
if (av != NULL_KEY && llGetPermissionsKey() == NULL_KEY)
{ llRequestPermissions(av, PERMISSION_CONTROL_CAMERA);
}
}
}
run_time_permissions(integer perms)
{ if (perms & PERMISSION_CONTROL_CAMERA)
{ llInstantMessage(llGetPermissionsKey(),
"This device allows the spectator cameras to be centrally controlled."
+"\nPlease : "
+"\n1] Ensure you are NOT in mouselook."
+"\n2] Reset your camera by pushing the escape button 3 or 4 times."
+"\nNOTE: If the controller avatar's drawdistance is greater than yours, "
+"you may experience being 'left behind' at some point. Either increase "
+"your draw distance, or reset your camera again (hit escape a few times) "
+"after a short while and hopefully the controllers camera is closer and "
+"tracking will resume.\nObviously it helps to let the controller know if "
+"they are too far away, but perhaps your drawdistance could also be higher."
+"\n[ctrl-P.... graphics tab...'custom' checkbox... 'drawdistance' slider... increase it a bit]"
);
llSetTimerEvent(gFrequency);
}
}
timer()
{ if (llGetPermissionsKey())
{ string desc = llList2String(llGetObjectDetails(llGetLinkKey(LINK_ROOT), [OBJECT_DESC]),0);
integer index = llSubStringIndex(desc, "#");
vector pos = (vector)llGetSubString(desc, 0, index-1);
if (pos == ZERO_VECTOR)
{ f_camDefault();
return;
}
rotation rot = (rotation)llGetSubString(desc, index+1, -1);
llSetCameraParams([
CAMERA_ACTIVE, 1 //1 is active, 0 is inactive
,CAMERA_BEHINDNESS_ANGLE, 0.0 //(0 to 180) degrees
//,CAMERA_BEHINDNESS_LAG, 0.05 //(0 to 3) seconds
,CAMERA_DISTANCE, 0.0 //(0.5 to 10) meters
,CAMERA_FOCUS, pos + llRot2Fwd(rot) //Region-relative
,CAMERA_FOCUS_LAG, 0.05 //(0 to 3) seconds
,CAMERA_FOCUS_LOCKED, TRUE //(TRUE or FALSE)
,CAMERA_FOCUS_THRESHOLD, 0.0 //(0 to 4) meters
,CAMERA_POSITION, pos //Region-relative position
,CAMERA_POSITION_LAG, 0.05 //(0 to 3) seconds
,CAMERA_POSITION_LOCKED, TRUE //(TRUE or FALSE)
,CAMERA_POSITION_THRESHOLD, 0.0 //(0 to 4) meters
,CAMERA_FOCUS_OFFSET, ZERO_VECTOR //<-10,-10,-10> to <10,10,10> meters
]);
}
else
{ llSetTimerEvent(0.0);
}
}
}
//=========================================================================