03-15-2006 16:34
Well, after the neat demo in Ben Linden's video of being able to set up cameras for people walking around your builds, 3D game style, I thought this would be useful: an attachment for folks to wear that lets them grant permission for freestanding objects to control the camera.

Put onto a small prim, attach to HUD, and put a suitable texture on as a "release camera" button (I tried to make one at ea602e9a-bb02-4a4b-1cf1-36cfaf41ebdc, but it looks really scrappy and I'm going to do it over :) )

CODE

key known_owner = NULL_KEY;
list permslist = [];
integer reqinprogress = FALSE;
key reqkey;
key reqob;
integer listenhandle;

default
{
attach(key whoto) {
if (whoto != NULL_KEY) {
if (known_owner != llGetOwner()) {
permslist = [];
known_owner = llGetOwner();
}
reqinprogress = FALSE;
llSetAlpha(0.0,ALL_SIDES);
llRequestPermissions(llGetOwner(),PERMISSION_CONTROL_CAMERA);
} else {
llRequestPermissions(llGetOwner(),0);
}
}

run_time_permissions(integer perms) {
if (perms & PERMISSION_CONTROL_CAMERA) {
llListen(-13542,"",NULL_KEY,"");
} else {
if (llGetAttached() != 0) llOwnerSay("Unable to get permission to control camera.");
}
}

listen(integer channel, string name, key speaker, string message) {
if (channel == -9897) {
llListenRemove(listenhandle);
reqinprogress = FALSE;
if (message == "Yes") {
permslist += reqkey;
llSay(-13542,(string)reqob+"allow");
} else {
llSay(-13542,(string)reqob+"deny");
}
return;
}
key targetKey = llGetSubString(message,0,35);
string command = llGetSubString(message,36,-1);
key remowner = llGetOwnerKey(speaker);
if (targetKey != llGetOwner()) return;
if (llListFindList(permslist,[remowner]) == -1) {
if (command == "request") {
if (reqinprogress) {
llSay(-13542,(string)speaker+"busy");
return;
}
reqinprogress = TRUE;
listenhandle = llListen(-9897,"",llGetOwner(),"");
reqkey = remowner;
reqob = speaker;
llRequestAgentData(reqkey,DATA_NAME);
return;
} else return;
}

if (command == "release") {
llClearCameraParams();
llSetAlpha(0.0,ALL_SIDES);
return;
}

list camerastuff = llParseString2List(command,["|"],[]);

list castedcamerastuff = [];
integer t;
integer status = 0;
for (t=0; t<llGetListLength(camerastuff); t++) {

if (status == 0) { // Command
integer val = llList2Integer(camerastuff,t);
castedcamerastuff += val;
if (val == CAMERA_PITCH) status = 1; // float
if (val == CAMERA_FOCUS_OFFSET) status = 2; // vector
if (val == CAMERA_POSITION_LAG) status = 1;
if (val == CAMERA_FOCUS_LAG) status = 1;
if (val == CAMERA_DISTANCE) status = 1;
if (val == CAMERA_BEHINDNESS_ANGLE) status = 1;
if (val == CAMERA_BEHINDNESS_LAG) status = 1;
if (val == CAMERA_POSITION_THRESHOLD) status = 1;
if (val == CAMERA_FOCUS_THRESHOLD) status = 1;
if (val == CAMERA_ACTIVE) status = 3; // int
if (val == CAMERA_POSITION) status = 2;
if (val == CAMERA_FOCUS) status = 2;
if (val == CAMERA_POSITION_LOCKED) status = 3;
if (val == CAMERA_FOCUS_LOCKED) status = 3;
} else {
if (status == 1) { castedcamerastuff += (float)(llList2String(camerastuff,t));}
if (status == 2) { castedcamerastuff += (vector)(llList2String(camerastuff,t));}
if (status == 3) { castedcamerastuff += (integer)(llList2String(camerastuff,t));}
status = 0;
}
}

llSetCameraParams(castedcamerastuff);
llSetAlpha(1.0,ALL_SIDES);
}

touch_start(integer touchers) {
llClearCameraParams();
llSetAlpha(0.0,ALL_SIDES);

}

dataserver(key qid, string data) {
llDialog(llGetOwner(),"Do you want to allow objects owned by " + data + " to control your camera?",["Yes","No"],-9897);
}

}


Freestanding objects wanting to control an av's camera should send the av's key plus "request" on channel -13542; if they recieve their own key followed by "allow" then can proceed to control the av's camera by sending the av's key followed by the list of camera params, seperated by |'s, again on channel -13542.