Jump to content

Camera Controls - Problems with Theory and Practice.


Frankie Rockett
 Share

You are about to reply to a thread that has been inactive for 470 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hi
I'm sure this is basic to anyone with Camera Control knowledge but it's too opaque for me make progress with.

I want to offset the camera view from just behind and above my avatar (the default position) to a lot behind and a lot above, say 500m behind and say 1000m above. When I try with settings like those below, I see a momentary 'ping' to a distant view that, within a millisecond catapults back to the standard view. I tried switching on Camera_position_locked but that got me nowhere. What am I doing wrong here please?

    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, 3.0, // ( 0.5 to 10) meters
        //CAMERA_FOCUS, <0,0,5>, // 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, <0, 500, 1000>, // 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, <0, 0, 1.5> // <-10,-10,-10> to <10,10,10> meters
    ]);

The bigger part of the problem here for my understanding is that all the many parameter names are not really explained anywhere in the Wiki. For example - Camera_Position_lag and Camera_Behindness_Lag. Many seem to be synonyms for each other. Then we have other obscure stuff like Camera_Position_Threshold for example. What on earth does that control? I've worked as a RL videographer and all this maps onto nothing I've ever encountered, so if anyone knows of, or has even written, a help page on what's actually meant by these (and other) rule parameter names then please do pass it along too. Thank you!

  • Thanks 1
Link to comment
Share on other sites

So, if you haven't checked the wiki yet: https://wiki.secondlife.com/wiki/LlSetCameraParams

That said, the basic thing you're trying to do isn't really possible. The best you could get for a 'top down' view is setting CAMERA_DISTANCE to 50, and CAMERA_PITCH to 80.

It's been a while since I've played with the camera, but IIRC, it's basically impossible to to do anything other than small adjustments to how the camera normally follows you, or set the camera at specific in-world locations (which must be in the same region as you)

For a demo of setting the camera to specific in-world locations, here's the script for a little toy I made a while back:

Quote
list camPos; // strided list of cam position, look-at.

vector cSELECTED = <0,1,0>; // green when selected.
vector cUNSELECTED = <1,1,1>; // white when not selected.
vector cUNSET = <0.25,0,0>; // before has a cam position assigned.

push_camera(integer index) // set client side camera params.
{   vector pos = llList2Vector(camPos,2*index);
    vector focus = llList2Vector(camPos,1+(2*index));
    if(pos)
    {   llOwnerSay("Push "+(string)index); // debug.
        llSetCameraParams(
        [   CAMERA_ACTIVE,TRUE,
            CAMERA_FOCUS_LOCKED,TRUE,
            CAMERA_FOCUS, focus,
            CAMERA_POSITION_LOCKED,TRUE,
            CAMERA_POSITION, pos
        ]);
        // Unselect first or else will be issue when re-selecting same slot.
        vector cPrev = cUNSET;
        if(llList2Vector(camPos,2*camIndexPrev)){cPrev = cUNSELECTED;}
        llSetLinkColor(1+(camIndexPrev/8),cPrev,camIndexPrev&7);
        llSetLinkColor(1+(index/8),cSELECTED,index&7);
    }
    camIndexPrev=camIndex;
}
pull_camera(integer index) // get camera info and pull to list.
{   if(maySet)
    {   llOwnerSay("Pull "+(string)index); // debug.
        vector pos = llGetCameraPos();
        vector focus = pos+<1,0,0>*llGetCameraRot();
        
        camPos = llListReplaceList(camPos,[pos,focus],2*index,2*index+1);
    }
    camIndexPrev=camIndex;
}
wipe_camera(integer index) // remove camera Info from list.
{   llClearCameraParams();
    if(maySet)
    {   llOwnerSay("Wipe "+(string)index); // debug.
        camPos = llListReplaceList(camPos,[ZERO_VECTOR,ZERO_VECTOR],2*index,2*index+1);
    }
    vector cPrev = cUNSET;
    if(llList2Vector(camPos,2*camIndexPrev)){cPrev = cUNSELECTED;}
    llSetLinkColor(1+(camIndexPrev/8),cPrev,camIndexPrev&7);
    //llSetLinkColor(1+(index/8),cUNSELECTED,index&7);
    camIndexPrev=camIndex;
}
integer camIndexPrev;
integer camIndex =-1;

integer maySet = TRUE; // allowed to add or clear camera positions.

default
{   state_entry()
    {   integer l = 16;
        while(~--l)
        {   camPos+=[ZERO_VECTOR,ZERO_VECTOR];
        }
        llSetLinkColor(LINK_SET,cUNSET,ALL_SIDES);
        llRequestPermissions(llGetOwner(),PERMISSION_TRACK_CAMERA|PERMISSION_CONTROL_CAMERA);
    }
    changed(integer c)
    {   if(c&CHANGED_OWNER)
        {   maySet = FALSE;
        }
    }
    attach(key ID)
    {   if(ID)
        {   //maySet=FALSE; // debug!
            llRequestPermissions(llGetOwner(),PERMISSION_TRACK_CAMERA|PERMISSION_CONTROL_CAMERA);
        }
    }
    run_time_permissions(integer perms)
    {   if(perms==(PERMISSION_TRACK_CAMERA|PERMISSION_CONTROL_CAMERA))
        {   llClearCameraParams(); // debug.
            if(~camIndex)
            {   push_camera(camIndex);
            }
        }
    }
    touch_start(integer total_number)
    {   integer index = llDetectedTouchFace(0)+(8*(llDetectedLinkNumber(0)-1));
        if(llList2Vector(camPos,2*index))
        {   if(index==camIndex)
            {   wipe_camera(camIndex=index);
            }else
            {   push_camera(camIndex=index);
            }
        }else
        {   if(index==camIndex)
            {   pull_camera(camIndex=index);
                push_camera(index);
            }else
            {   wipe_camera(camIndex=index); 
            //  ^ redundantly replaces zero vectors with zero vectors, but adds consistancy.
            }
        }
    }
}

this expects to be in a linkset with 2 8-faced display panels, but should work ok in just a 5-face tortured cube or something.

Getting LSL camera control to work reliably for something like cinematography seems iffy to me though. Here's a demo of me haphazardly combining 2 proof of concept level toys and walking around my house (Currently for sale!)

 

Link to comment
Share on other sites

Not sure this helps, but I think of llSetCameraParams as providing ways to control two kinds of cameras, one a fixed shot, and the other tracking and dolly shots. Either way, these translate into instructions the script sends to the viewer, so they're ultimately subject to the viewer's constraints at best.

The fixed shot cam lets you put the cam arbitrarily(?) far away, and any time you want the cam to move or point elsewhere the script must call the function again. In contrast, tracking shots are much more constrained and use more of the parameters. They're fine for simple fine-tuning of the cam position relative the avatar of the viewer, but I've never gotten them to track anything else* nor dolly except yoked to that avatar's movement.

For the extreme distances here, I think you're stuck with the fixed shot approach, for which the relevant parameters are just those in @Quistess Alpha's script above. It's possible to update the cam on a timer a few times a second which may be fine for such a long shot, but will be unacceptably jittery for nearer range videography where instead the tracking cam parameters are relevant but limited.

______________________
*Unscripted, the viewer can track other moving objects besides its avatar—sometimes annoyingly, as when it latches focus on some rotating thing in view and spins around—but I don't think there's any way for a script to create that effect. And as far as I know, even the viewer itself can only dolly corresponding to the avatar's motion.

  • Like 1
Link to comment
Share on other sites

5 hours ago, Qie Niangao said:

lets you put the cam arbitrarily(?) far away,

I've not tested it, but my suspicion is that since the camera's position is specified in region coordinates, things might go awkwardly if you try and put it too far into another region.

Link to comment
Share on other sites

Hello!

Thank you very much for both your replies! First, to clear up some misunderstandings (sorry about them) Quistess. Thank you for the wiki link but I have read it. When I said "many parameter names are not really explained anywhere in the Wiki", that was intended to communicate that I have in fact read the Wiki as a precursor to being unhappy with it's clarity. Also, I'm not concerned with trying to put the camera view outside of the origin region. Not sure how I mislead you to think that.

Actually I want to shift the view - vertically - to a static position such that I can view a scene taking place directly ahead (not below) at a greater altitude. By way of an analogy, there's a great cabaret show in SL called 'Idle Rogue' (free plug for them there!) in which you take a seat in the theater and watch a show that has several instant set changes. This is accomplished it seems, by having several stages pre-set at various altitudes above the theatre. The code in the seats switches the audience's view higher and lower at key trigger points so you experience this seamlessly smooth transition between acts/numbers.

My intention relies on exactly the same mechanism - figuring out how to reset the X and Y view to a new 'standard position', then setting and switching the Z position according to a series of triggers.

I think Qie's remarks were very helpful in separating fixed shots (that I want) from those that center of the avatar from various positions (which I don't want at all). Although he mentions the "The fixed shot cam lets you put the cam arbitrarily(?) far away" he doesn't say how/where I create a 'fixed shot cam'. He references Quistess' code but there's a lot there to dig through and I see nothing that immediately says 'fixed cam' to me unfortunately. I think I'm mostly there in that we've identified it's a fixed cam function that I need, but can you give me an example of how to relocate the XY and Z to some arbitrary fresh locatin (in the same sim) that is substantially more than 10 meters away from the default, please?

Thank you!

 

Edited by Frankie Rockett
Link to comment
Share on other sites

20 minutes ago, Frankie Rockett said:

XY and Z to some arbitrary fresh locatin (in the same sim) that is substantially more than 10 meters away from the default, please?

Ahh thank you for the clarification. my 'outside the region' concern ws that because regions are only 256x256 meters, your example of 500,1000 would neccessarily be outside the region. (500 is bigger than 256). 

SL's camera is ~very fussy, so unfortunately, I do not believe it is possible to get it to smoothly transition between 2 (specified) locations (you can get it to move from avatar view to non-avatar view smoothly though). That said, assuming you have all the other boiler plate in-place (mostly permission requests and UI) switching to a specific camera view should be as simple as

llSetCameraParams(
        [   CAMERA_ACTIVE,TRUE,
            CAMERA_FOCUS_LOCKED,TRUE,
            CAMERA_FOCUS, focus,
            CAMERA_POSITION_LOCKED,TRUE,
            CAMERA_POSITION, pos
        ]);
        

where pos is the position of the camera in region coordinates, and focus is the position of the thing the camera is looking at in region coordinates. Note that the LOCKED, TRUE settings are before the positions. IIRC the order matters to some extent.

Link to comment
Share on other sites

Hi!

Thank you for that. Truth is I was playing in a vast sandbox when I came up with '500' etc. Sorry to mislead us both!

Yes I have the rest in place, well, in a rough and ready basic test-bed kind of way. Thank you for the tip about locking first.

I'm playing with it as we speak, using the latest Firestorm, and I find that even sticking just with those four rules (five counting 'Camera_Active') and in that order, it only wants to give me an aerial view of my avatar, or, a look vertically up at the sun. Any clues, or is that the limit of the cam control? I could work around it by having my 'stage' arranged facing down so I could look up at it I suppose. At the moment I don't anticipate any avatars featuring but if they did they'd fall off the stage into the viewers face! So it would be nice if I could arrange a view, in any direction, straight and level. Thoughts?

Edited by Frankie Rockett
Link to comment
Share on other sites

1 hour ago, Frankie Rockett said:

Any clues,

after setting the parameters the first time, sleep(0.5); then see if setting the exact same parameters gives you a different result. If it does, the issue is that SL's camera doesn't really "like" moving over wide distances or changing angles rapidly, and can get stuck halfway between where it was and where you told it to go.

ETA: After a bit of testing, it seems the camera ~really doesn't like moving over large distances quickly. Your best bet might be to teleport the avatar to within a 'reasonable distance' of where you want their camera before you take their camera control and teleport them back. Or you could try getting them to lock onto an object with 'CLICK_ACTION_ZOOM' set, and somehow move that quickly but not too quickly to the destination before moving over to controlled camera. These suggestions don't sound like very user-friendly hacks though :/

After even more testing, if you move more than ~100 meters away from a "Fixed camera" it stops being fixed and sticks to a sphere around the avatar.

Make sure "Disable camera constraints" is checked in your viewer under the "move and view" tab of preferences. Otherwise, every possible method of moving your camera more than ~100 meters from your avatar will fail. (for not-firestorm, it may be under 'advanced options' and/or debug settings "DisableCameraConstraints")

Edited by Quistess Alpha
  • Like 1
Link to comment
Share on other sites

I completely forgot about "Disable camera constraints" which is a real prerequisite here. But that must somehow be already in place for the multi-level cabaret show, unless there's something else unexplained going on there.

Anyway, by way of illustration, here's a dopey attachment script that, on reset,. reports the current cam parameters for re-use, and then on touch toggles between a pair of those saved as SKY_ and GROUND_PARAMS global variables. (The resulting views for these saved parameters will make more sense on the Myron region.)

list SKY_PARAMS = 
    [ CAMERA_POSITION, <250.07240, 83.60931, 2010.69700>
    , CAMERA_FOCUS, <249.09470, 83.68665, 2010.50100>
    ];
list GROUND_PARAMS =
    [ CAMERA_POSITION, <241.49040, 31.72809, 35.39202>
    , CAMERA_FOCUS, <241.07040, 32.62868, 35.28009>
    ];
integer toggle;

default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TRACK_CAMERA | PERMISSION_CONTROL_CAMERA);
    }
    run_time_permissions(integer perms)
    {
        if (PERMISSION_TRACK_CAMERA & perms)
        {
            vector camPos = llGetCameraPos();
            llOwnerSay("CAMERA_POSITION, "+ (string)camPos
                +"\n, CAMERA_FOCUS, "+(string)(camPos + llRot2Fwd(llGetCameraRot())));
        }
    }
    touch_start(integer void)
    {
        if ((PERMISSION_CONTROL_CAMERA & llGetPermissions())
            && (llDetectedKey(0) == llGetPermissionsKey()))
        {
            list params = [ CAMERA_ACTIVE, TRUE, CAMERA_FOCUS_LOCKED, TRUE, CAMERA_POSITION_LOCKED, TRUE ];
            if (toggle = !toggle)   // assignment
                params += SKY_PARAMS;
            else
                params += GROUND_PARAMS;
            llSetCameraParams(params);
        }
    }
}

 

  • Like 1
Link to comment
Share on other sites

Hi Gang!
Thank you Quistess (and also Qie) for mentioning 'Disable Camera Constraints'. Actually I have that disabled by default so it's not an issue but thank you for your forensic attention to detail in helping nail this.

I have success! But success bound up with mystery. Here's what happened. My test-bed was based on avatar touch to initiate perms request, and a second touch to move the camera. It was a pain and the only way to cancel the effect was to delete the prim and re-rez the prim. So I set about changing it to work 'on-sit'. Except nothing I did would trigger the permissions request this time. I tried moving the permissions request around so many times I was exhausted. In the end with them moved to a pretty obscure position, everything worked as intended - even taking the camera up to a height of 1000 meters. Yaay! Except one weird note - it no longer actually asks for permissions, it just... works. No permissions dialogue box pops up. Yet it works anyway. Here's the script:

// Camera Controller
// December 2022


key agent;

take_camera_control(key agent)
{
    llOwnerSay("Taking Camera Control"); // say function name for debugging
    llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
    llSetCameraParams([CAMERA_ACTIVE, 1]); // 1 is active, 0 is inactive
}


release_camera_control(key agent)
{
    llOwnerSay("Releasing Camera"); // say function name for debugging
    llSetCameraParams([CAMERA_ACTIVE, 0]); // 1 is active, 0 is inactive
     llClearCameraParams( );
} 



test_cam()
{ 
    llOwnerSay("Changing Viewpoint"); // say function name for debugging
    llClearCameraParams(); // reset camera to default
    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, 3.0, // ( 0.5 to 10) meters
        CAMERA_FOCUS_LOCKED, TRUE, // (TRUE or FALSE)
        CAMERA_FOCUS, <500, 12, 1000>, // region relative position
//        CAMERA_FOCUS_LAG, 0.0 , // (0 to 3) seconds
//        CAMERA_FOCUS_THRESHOLD, 4.0, // (0 to 4) meters
//        CAMERA_PITCH, 30.0, // (-45 to 80) degrees
        CAMERA_POSITION_LOCKED, TRUE, // (TRUE or FALSE)
        CAMERA_POSITION, <500, 6, 1000> // region relative position
//        CAMERA_POSITION_LAG, 0.0, // (0 to 3) seconds
//        CAMERA_POSITION_THRESHOLD, 0.0 // (0 to 4) meters
//        CAMERA_FOCUS_OFFSET, <0, 0, 1.5> // <-10,-10,-10> to <10,10,10> meters
    ]);
}



default
{
    state_entry()
    {
        llSay(0, "Script running");
        rotation rot = llEuler2Rot( <0.0,  0.0, 270.0> * DEG_TO_RAD );
        llSitTarget(<0.0, -0.3, 0.37>,rot);
    }
      
    
    changed(integer n)
    { // STANDING
        if(n & CHANGED_LINK)
        {
            agent = llAvatarOnSitTarget();
            if(agent!=NULL_KEY)
            {
                take_camera_control(agent);
            }
            else
            {
//              llSetAlpha(1,ALL_SIDES);
                release_camera_control(llDetectedKey(0));
            }
        }
    }
    
    run_time_permissions(integer n)
    { // SITTING
        test_cam();
    }     
}

I am very tempted to conclude "if it ain't broke don't fix it" but this not asking for Permissions thing haunts me slightly, like it might break under some viewers perhaps? Thoughts, or am I home and dry?

Lastly, I tried calling the move cam function twice with a 0.5 sec pause as you suggested Quistess, but ultimately I took it out again as, once the Permissions request was sidelined, it worked without need of the pause.

Link to comment
Share on other sites

Most permission requests are tacit if called from a script in an attachment or a sat-upon object—but those are the only kinds of objects from which PERMISSION_CONTROL_CAMERA can be granted (except Experience scripts IIRC), so it's a bit mysterious that there were ever explicit requests. But anyway, not seeing an explicit request isn't a sign of trouble.

That doesn't mean there are no problems here. It's not really safe to assume permissions are granted immediately upon asking for them (as in the take_camera_control function here). Rather, the script should request permissions and only use them when it's sure to have received a corresponding run_time_permissions() event. If the permissions-requiring functions aren't called right in the run_time_permissions event, the script should guard them with a test of llGetPermissions() and often a check that llGetPermissionsKey() refers to the avatar for which the functions are intended. The current script may work without trouble, but for this reason it's not quite "home and dry".

Link to comment
Share on other sites

You are essentially echoing my own concern Qie -  but admittedly much more articulately so! So the question remains; what should I do about it?

If I check for permissions as you suggest, the check will fail and the camera won't move anywhere. It seems I have to find a way to really force the permission check, but I've tried everything I can imagine to force that already and it won't happen.

How can I definitely force the permission check?

Edited by Frankie Rockett
Correcting typos.
Link to comment
Share on other sites

2 hours ago, Frankie Rockett said:

How can I definitely force the permission check?

one paradigm I often use is to have some sort of global variable, say gMode, which can be used as a 'reminder' of why the permission request was sent:

integer gMode;
default
{
    state_entry()
    {   llSay(0, "Script running");
        rotation rot = llEuler2Rot( <0.0,  0.0, 270.0> * DEG_TO_RAD );
        llSitTarget(<0.0, -0.3, 0.37>,rot);
    }
    changed(integer n)
    { // STANDING
        if(n & CHANGED_LINK)
        {
            agent = llAvatarOnSitTarget();
            if(agent!=NULL_KEY)
            {	gMode = 1; //take_camera_control(agent);
                llRequestPermissions(agent,PERMISSION_CONTROL_CAMERA);
            }
            else
            {	gMode = 2; //release_camera_control(agent);
                llRequestPermissions(agent,PERMISSION_CONTROL_CAMERA);
//              llSetAlpha(1,ALL_SIDES);
            }
        }
    }
    
    run_time_permissions(integer n)
    { // SITTING
        if(n!=PERMISSION_CONTROL_CAMERA)
        {   return;
        }
        if(gMode==0)
        {   test_cam();
        }else if(gMode==1)
        {   take_camera_control(llGetPermissionsKey());
        }else if(gMode==2)
        {   release_camera_control(llGetPermissionsKey());
        }
        gMode=0;
    }     
}

(off the top of my head, unchecked modification as an example)

Edited by Quistess Alpha
Link to comment
Share on other sites

Hi

Thank you Quintess. I tried your code (after adding back in the function calls!) and it executes as it did prior to your intervention, ie it works, sans any permission check. I did find that on the 2nd pass through the 'Changed' portion, the error message "Unable to find specified agent to request permissions" was generated, but this was ONLY generated upon standing - not sitting - on the prim!

So I looked hard at the assignment "agent = llAvatarOnSitTarget();" and wondered if it was getting over-written between the stand and the sit? There's no way it can be, but that didn't stop me tying myself in knots trying to ensure that fact! Actually I assigned an opening vale of "00000000-0000-0000-0000-000000000001" to 'agent' (notice the trailing '1') so that I could later test as follows:
 if (agent == NULL_KEY || agent == "00000000-0000-0000-0000-000000000001")
            agent = llAvatarOnSitTarget()
(Crazy huh? - but that's what this is doing to me!), and the resulting error message changed to:
" Camera control currently only supported for attachments and objects on which you are sitting."!!!!

If that's not a throw your hands up in the air moment, I don't know what is!
So it looks like the only way this (theoretically) simple bit of script will run is if I ignore the fact that it doesn't ask for permissions, despite there being every reason in the world why it should. Very, very frustrating!!!
Thank you for your very best endeavors though. The main thing is I have it working at all of course, and for that I am sooo grateful - to both of you!
           

Link to comment
Share on other sites

5 hours ago, Frankie Rockett said:

So I looked hard at the assignment "agent = llAvatarOnSitTarget();" and wondered if it was getting over-written between the stand and the sit?

Oh, duh, when you stand up, you're no longer on the thing so the llAvatarOnSitTarget(); is NULL_KEY. Most modern viewers should automatically stop animations camera control caused by a seat after standing from it, so it should be safe to comment out the case where the avatar stands.

I also forgot to mention with this structure, the permission requests in the functions themselves should be superfluous. (because they're always called form within the event confirming the permissions were granted)

Edited by Quistess Alpha
Link to comment
Share on other sites

Hi Quintess. Thank you for that. Yes, I wondered the same thing - that a now standing Avatar would return NULL_KEY. Thank you for confirming that.

I don't follow/understand your second sentence though. " the permission requests in the functions themselves should be superfluous". Do you mean I can stop worrying about trying to get the explicit Permission request dialogue box up and just count this as 'working' after all? Thank you.

Link to comment
Share on other sites

42 minutes ago, Frankie Rockett said:

Do you mean I can stop worrying about trying to get the explicit Permission request dialogue box up and just count this as 'working' after all?

I meant you could comment out the permission request inside the take_camera_control() function.

If you want explicit boxes (perhaps just for your own sanity) you can add an additional permission you don't need that doesn't have auto-grant status. PERMISSION_TELEPORT would work nicely (anyone can grant and it is never auto-granted):

llRequestPermissions(agent,PERMISSION_CONTROL_CAMERA|PERMISSION_TELEPORT);
Link to comment
Share on other sites

I never thought of requesting PERMISSION_TELEPORT like that, so I had to give it a try and indeed it generates that explicit permissions dialog. But it has an interesting effect: it causes permissions to be revoked immediately when the sitter stands, so the script can't release the camera. (I'm not sure if that's because of the explicit permissions request, or the PERMISSION_TELEPORT specifically.)

In any case, I don't think there's any point even trying to request camera permission after the agent stood because a script can only control the cam for seated agents (or those to whom the script is attached).

Anyway, reverting to the implicit permissions grant for just PERMISSION_CONTROL_CAMERA, something like this seems to work:


default
{
    state_entry()
    {
        llSitTarget(<0.0, -0.3, 0.37>, llEuler2Rot( <0.0,  0.0, 270.0> * DEG_TO_RAD ));
    }
    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            key agent = llAvatarOnSitTarget();
            if (agent != NULL_KEY)  // somebody sat, so let's try to take their cam
                llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
            else    // somebody stood
            if ((PERMISSION_CONTROL_CAMERA & llGetPermissions())
                && (NULL_KEY != llGetPermissionsKey()))  // and we can still release their cam
            {
                llClearCameraParams(); // reset camera to default
                llSetCameraParams([CAMERA_ACTIVE, FALSE]);
            }
        }
    }
    run_time_permissions(integer perms)
    {
        if (perms & PERMISSION_CONTROL_CAMERA)
        {
            llSetCameraParams([
                CAMERA_ACTIVE, TRUE,
                CAMERA_FOCUS_LOCKED, TRUE, // (TRUE or FALSE)
                CAMERA_FOCUS, <500, 12, 1000>, // region relative position
                CAMERA_POSITION_LOCKED, TRUE, // (TRUE or FALSE)
                CAMERA_POSITION, <500, 6, 1000> // region relative position
            ]);
        }
    }
}

 

  • Thanks 1
Link to comment
Share on other sites

Thank you for the very compact re-write of my own rather verbose and inefficient original code Qie. After that things went downhill though. Not only does it continue not to put up the Permission dialogue, but also, it doesn't work at all. It doesn't move the camera anywhere. It doesn't execute any functionality.

Yet you said "something like this seems to work". Have you tried it?? If so, how did your test differ from my own? I just rezzed a prim in a sandbox, put your code in and then sat on the prim. Nothing happened. What did you do that was any different?

Thank you for trying anyway. It's much appreciated.

Link to comment
Share on other sites

I did try it, and I tried it again just now and it's still working for me. Before looking for anything too weird, I wonder if by any chance there was some problem saving the script so it got set to NOT running for you? Or could you need to press Escape a time or two to let the scripted camera take effect? (Kinda grasping at straws here, I realize.)

As for getting the explicit dialog, yeah, I didn't find a way to do that without causing permissions to be lost immediately upon standing—so no way to release the camera control—which seems a bigger problem. That deserves more investigation, though, because other permissions such as animation are revoked upon standing but after the script gets a chance to stop animations, and I've never been clear how constrained that grace period is.

Edited by Qie Niangao
typo
Link to comment
Share on other sites

Hi Qie!
Thank you for confirming your test worked. I re-tried it, making sure that it was set to run. It was. Then something strange, inexplicable, happened. I hit Esc as you suggested - Bam! It worked!! One hit of Esc only. Fabulous! I stood, and tried again. Second time it worked as it should - no need for Esc. A third and fourth time and it continued to work. I should say by 'work' I mean it still won't bother to give me a Permissions dialogue, but it does move the camera as intended. Unfortunately in the grand scheme this hasn't solved the failure to generate a Permission dialogue but honestly, I'm happy to live with that at this stage. Every problem has a cost/benefit calculation and this one has exceeded it's own budget! You and and Quintess have given so much of your time energy and wonderful insights to this problem. Between you have got it WORKING! - never mind the nicety of permissions at this point. If any user is unhappy and wouldn't have given permission, they can just stand up again!

Also I have to bow out of this forum (for now) due to RL pressures around Christmas RL, so sincerely - thank you. If you do feel interested in sharing further thoughts or comments, I will see them and respond in the New Year. So for now - thank you, and have a Happy Christmas/Holiday!

  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 470 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...