CODE
vector cameraPos;
float maxCameraDist = 15;
integer cameraOn = TRUE;
integer scanning = FALSE;
integer noWalls = FALSE;
cameraToggle(key agent) {
if (cameraOn) {
release_camera_control(agent);
llSetTimerEvent(0);
llSensorRemove();
} else {
take_camera_control(agent);
llSetTimerEvent(1);
}
}
take_camera_control(key agent) {
llOwnerSay("take_camera_control"); // say function name for debugging
llOwnerSay( (string)agent);
llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
}
release_camera_control(key agent) {
llOwnerSay("release_camera_control"); // say function name for debugging
llSetCameraParams([CAMERA_ACTIVE, 0]); // 1 is active, 0 is inactive
llReleaseCamera(agent);
cameraOn = FALSE;
}
positionCamera() {
if (cameraOn) {
llSetCameraParams([
CAMERA_ACTIVE, 1, // 1 is active, 0 is inactive
CAMERA_BEHINDNESS_ANGLE, 0.0, // (0 to 180) degrees
CAMERA_BEHINDNESS_LAG, 0.0, // (0 to 3) seconds
CAMERA_DISTANCE, 0.0, // ( 0.5 to 10) meters
CAMERA_FOCUS, cameraPos, // region relative position
CAMERA_FOCUS_LAG, 0.0 , // (0 to 3) seconds
CAMERA_FOCUS_LOCKED, FALSE, // (TRUE or FALSE)
CAMERA_FOCUS_THRESHOLD, 0.0, // (0 to 4) meters
// CAMERA_PITCH, 80.0, // (-45 to 80) degrees
CAMERA_POSITION, cameraPos, // region relative position
CAMERA_POSITION_LAG, 0.0, // (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
]);
llSetTimerEvent(1);
}
}
default {
state_entry () {
llSensor("", NULL_KEY, PASSIVE | ACTIVE | SCRIPTED, maxCameraDist / 1.5, PI);
cameraToggle(llGetOwner());
}
timer() {
if (llVecDist(llGetPos(), cameraPos) > maxCameraDist && !scanning) {
// llOwnerSay("Distance from camera: " + (string)llVecDist(llGetPos(), cameraPos));
llSensorRepeat("", NULL_KEY, PASSIVE | ACTIVE | SCRIPTED, maxCameraDist / 1.5, PI, 0.5);
scanning = TRUE;
llSetTimerEvent(0);
}
}
sensor(integer num) {
scanning = FALSE;
vector myPos = llGetPos();
// llOwnerSay("myPos: " + (string)myPos);
integer p;
for (p = 0; p < num; p++) {
vector scannedPos = llDetectedPos(p);
// llOwnerSay("scannedPos(" + (string)p + "): " + (string)scannedPos);
if (llVecDist(scannedPos, myPos) < maxCameraDist && llVecDist(scannedPos, myPos) < llVecDist(cameraPos, myPos)) {
if (scannedPos.z > myPos.z+1) {
cameraPos = scannedPos;
}
}
}
// llOwnerSay("cameraPos: " + (string)cameraPos);
if (cameraPos == ZERO_VECTOR) {
cameraPos = myPos + <4,4,4>;
}
llSensorRemove();
vector rotPos = cameraPos + <2, 0, 0>;
rotation lookAtAv = llRotBetween(<1,0,0>, llVecNorm(llRot2Axis(llGetRot())));
vector newPos = cameraPos - ((cameraPos - rotPos) * lookAtAv);
positionCamera();
}
touch_start(integer total_number) {
cameraToggle(llDetectedKey(0));
}
run_time_permissions(integer perm) {
if ((perm & PERMISSION_CONTROL_CAMERA) == PERMISSION_CONTROL_CAMERA) {
llOwnerSay("Camera permissions have been taken");
cameraOn = TRUE;
positionCamera();
}
}
}
To decypher it, the camera scans the area around the avatar for a prim higher than the avatar and locks the camera there. It tracks the avatar's movement, but won't move from that spot. When the avatar gets too far away, it scans for another prim.
My problems are two fold:
- When you're farther away than the maxCameraDist and no other suitable prims are in sight, it SHOULD put your camera at llGetPos() + <4,4,4> until it finds something suitable, but doesn't.
- It's suppose to put the camera 2m out from the center of the prim it scanned, towards the avatar, but it doesn't.
I was going to use this as a camera example in a TeaZers class so it's essentially open source, but I'd like some help getting it working properly.
