Jump to content

How does the Avatar Ruler work?


animats
 Share

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

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

Recommended Posts

The free Avatar Ruler measures the height of an avatar accurately.How does it do that? It gets the right answer even when the avatar is sitting. That means it cant be using the bounding box dimensions; those change when sitting. It doesn't work by lowering a measuring object until it gets a collision, since it gets the same result for sitting and standing. It doesn't force the avatar into a standard pose. Can't read the script, unfortunately. Anyone know how that's done?

I want to get dimensional information from an avatar to adjust animations.

avatarheight.png

Edited by animats
Add screenshot
Link to comment
Share on other sites

If you look at the LSL wiki entry for llGetAgentSize, you'll see the answers to your questions:

  • The returned vector is an estimate calculated from the avatar's current shape including shoes. x is a constant 0.45[1], y is a constant 0.60[2], z is the approximate total height of all avatar's bones, with an arbitrary amount added or subtracted based on the current shape's "Hover" setting. Reported height is constrained to the range 1.1 to 2.45 meters, and does not include animation or mesh bone offsets. [3]
    • Due to the shape Hover setting, and mesh and animation offsets, it is not possible to use this function to determine the rendered height of an avatar with any degree of confidence.
  • As of Second Life Server 13.11.19.284082, the return value is the avatar's reported bounding box - <0.1, 0.1, 0.2> when standing. (Avatar bounding boxes have historically been redefined with major physics upgrades.) An avatar's bounding box changes when an avatar sits, while llGetAgentSize is constant for as long as the shape does not change.

Note that it is not true that "The free Avatar Ruler measures the height of an avatar accurately. "  In fact, there has been quite a lot of discussion over the years about how to measure the height of an avatar. Most of us use the value returned by llGetAgentSize directly or add a small semi-arbitrary amount to it (on the theory -- not well-substantiated as far as I know -- that llGetAgentSize returns the agent height at eyeball level).

Edited by Rolig Loon
Link to comment
Share on other sites

OK, llGetAgentSize gets the bounding box info as if standing and massages the numbers a bit. Thanks.

Can I measure an avatar by moving around another sensing object until it collides with the avatar, then recording the collision position? Suppose I wanted the offset of the back/buttocks from the center of the root? If I slowly move an object until it collides with the avatar, I should get a collision event. But what collides? Can I get mesh/mesh collision detection? Prims only? Or just the bounding box? Thanks.

(Goal: automatic pose ball adjustment.)

Link to comment
Share on other sites

You're after the Holy Grail (or one version of it).  Good luck.  I wish there were an easy answer, but because there's no way to measure exactly how far anyone's waist is from the soles of her feet (even discounting hover height and shoes), any guess you make isn't likely to be much better than simply 0.5 * AvSize.z .  When you add in the fact that the set height for any particular animation is likely to be different from the last one you used, you'll have enough uncertainty that you'll be better off letting the user make final adjustments manually with a dialog menu.

Link to comment
Share on other sites

2 hours ago, Rolig Loon said:

Note that it is not true that "The free Avatar Ruler measures the height of an avatar accurately. "  In fact, there has been quite a lot of discussion over the years about how to measure the height of an avatar. Most of us use the value returned by llGetAgentSize directly or add a small semi-arbitrary amount to it

The best 'avatar ruler I've found is the one made by Henri Beauchamp at Cool Products 

His uses llGetAgentSize, but also adds in 17 cm for the ground clearance between your hitbox and the ground to stop you making bump-bump noises everytime you walk... Biggest problem with avatar height is that for many years, the 'appearance editor' reported height didn't include all the things that actually affect your 'prim height'.

So back in Viewer 2 for example, you took appearance height, and added 6-14 inches for shoebase and ground clearance, if female, to get your SL height.

This is why 5'6" females end up being abused by "avi rulers" as GIANTS at 6'8"... 6 inches for clearance, 8 inches for platform soled high heeled shoes...



 

Link to comment
Share on other sites

19 hours ago, animats said:

OK, llGetAgentSize gets the bounding box info as if standing and massages the numbers a bit. Thanks.

Can I measure an avatar by moving around another sensing object until it collides with the avatar, then recording the collision position? Suppose I wanted the offset of the back/buttocks from the center of the root? If I slowly move an object until it collides with the avatar, I should get a collision event. But what collides? Can I get mesh/mesh collision detection? Prims only? Or just the bounding box? Thanks.

(Goal: automatic pose ball adjustment.)

An avatar only has one hitbox which is what is detected by collisions. The hitbox is centered at the avatar's raw position and is unaffected by animations.
You can make these visible under Developer > Render Metadata > Avatar Hitboxes

There isn't a way to detect where exactly the waist is (which would probably be the most important part for pose adjusting) or any other specific part of the avatar.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

How about this approach?

The avatar starts this by touching an object A.  Object A then rezzes a test object B (say a small ball), and somehow communicates with a script in B to tell it what avatar to talk to. B then does

    llRequestPermissions(avatarkey, PERMISSION_ATTACH | PERMISSION_TRIGGER_ANIMATION);
    
B waits for "run_time_permissions" event. Then B does

    llAttachToAvatarTemp(attach_point);
    
Useful attach points: ATTACH_PELVIS, ATTACH_BACK, ATTACH_LFOOT, ATTACH_RFOOT, ATTACH_BELLY.

Now, use llGetPos in B to get its position, and also get the root position of the avatar. Transmit those back to A's script, or use the info to move the avatar. When done, detach the test object. The test object doesn't have to be visible, of course.

Will that work?

(But see llGetPos "Caveats". This won't return the actual position of the attachment if animation is involved. Animation is entirely client-side. But it should get the basic position when not being animated.)

Link to comment
Share on other sites

5 minutes ago, animats said:

(But see llGetPos "Caveats". This won't return the actual position of the attachment if animation is involved. Animation is entirely client-side. But it should get the basic position when not being animated.)

Read the entire caveat:  "Visually, the reported position will only be correct if the object's root is attached to ATTACH_AVATAR_CENTER, at ZERO_ROTATION and ZERO_VECTOR."

Link to comment
Share on other sites

Right. But I think that's saying that, while the position and rotation are off, they're off by the difference between AVATAR_CENTER and the position of the root prim. So it may be possible to correct for this. Anyway, there's enough there to try things. Thanks.

Link to comment
Share on other sites

On 11/17/2017 at 12:00 AM, animats said:

How about this approach?

The avatar starts this by touching an object A.  Object A then rezzes a test object B (say a small ball), and somehow communicates with a script in B to tell it what avatar to talk to. B then does

    llRequestPermissions(avatarkey, PERMISSION_ATTACH | PERMISSION_TRIGGER_ANIMATION);
    
B waits for "run_time_permissions" event. Then B does

    llAttachToAvatarTemp(attach_point);
    
Useful attach points: ATTACH_PELVIS, ATTACH_BACK, ATTACH_LFOOT, ATTACH_RFOOT, ATTACH_BELLY.

Now, use llGetPos in B to get its position, and also get the root position of the avatar. Transmit those back to A's script, or use the info to move the avatar. When done, detach the test object. The test object doesn't have to be visible, of course.

Will that work?

(But see llGetPos "Caveats". This won't return the actual position of the attachment if animation is involved. Animation is entirely client-side. But it should get the basic position when not being animated.)

Instead of using temporary attachments (which requires the user to manually accept the prompt), you could just use llGetObjectDetails and OBJECT_POSITION.

The result is the same, as llGetPos returns the wearer's position in region coordinates, not the position of the attachment (ever).

But that still doesn't solve anything. It's just not possible to get an attachment's region coordinates, or relative position to avatar center (avatar's actual position). Even if the avatar is standing completely straight (no rotation on any bones), you still can't predict where any specific part of the body is. At best you can pick a proportional height (say at 46.5% of their height) and just assume that that is where every avatar's waist will be. It might make initial guesses more accurate, but won't eliminate the need for adjusting, so to put it bluntly it would be wasted effort over just default pose offsets which is much simpler to implement.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

On 16 November 2017 at 10:00 PM, animats said:

How about this approach?

The avatar starts this by touching an object A.  Object A then rezzes a test object B (say a small ball), and somehow communicates with a script in B to tell it what avatar to talk to. B then does

    llRequestPermissions(avatarkey, PERMISSION_ATTACH | PERMISSION_TRIGGER_ANIMATION);
    
B waits for "run_time_permissions" event. Then B does

    llAttachToAvatarTemp(attach_point);
    
Useful attach points: ATTACH_PELVIS, ATTACH_BACK, ATTACH_LFOOT, ATTACH_RFOOT, ATTACH_BELLY.

Now, use llGetPos in B to get its position, and also get the root position of the avatar. Transmit those back to A's script, or use the info to move the avatar. When done, detach the test object. The test object doesn't have to be visible, of course.

Will that work?

(But see llGetPos "Caveats". This won't return the actual position of the attachment if animation is involved. Animation is entirely client-side. But it should get the basic position when not being animated.)

Realistically... Not a chance in hell...

There are a couple of flaws in the idea...

1. The sitter has to give permission for each attacvhing object, unless you go through all the rigmarole for setting up an experience key.

2. llAttachToAvatarTemp is a "wear" command, so if they have anything worn already on those points, you run a risk of either knocking that item off, or failing to attach at all.

I can't speak for everyone, but generally, I'd object to a chair that removes my feet to ensure my ass isnt floating an inch above the seat cushion, and if I want a char that removes clothing, I use RLVa...
 

Link to comment
Share on other sites

I've been looking at what comes back for the bounding box during standing vs. sitting. The bounding box while standing is reasonable, and when sitting, the bounding box gets smaller in Z. But not by the right amount. It drops about 0.2m for a 2 meter avatar with about 0.5m lower legs.  That's just wrong.

Is there an explanation anywhere of exactly what the SL server knows and what the client knows about avatar position? I know that animation is purely visual and entirely client side, but sit/stand appears to be server side.  Which side calculates object collisions? Both sides seem to have a physics engine. Is all this documented somewhere?

Link to comment
Share on other sites

9 hours ago, animats said:

I've been looking at what comes back for the bounding box during standing vs. sitting. The bounding box while standing is reasonable, and when sitting, the bounding box gets smaller in Z. But not by the right amount. It drops about 0.2m for a 2 meter avatar with about 0.5m lower legs.  That's just wrong.

Is there an explanation anywhere of exactly what the SL server knows and what the client knows about avatar position? I know that animation is purely visual and entirely client side, but sit/stand appears to be server side.  Which side calculates object collisions? Both sides seem to have a physics engine. Is all this documented somewhere?

The server is "in charge" of everything. Scripts only know what the server knows, because scripts are run entirely server-side. As far as "client-side physics" go and what the client knows about avatar position, there's physics interpolation (client-side prediction between updates from the server), but that's about it.

The reason why the bounding box gets shorter is because while ground sitting, your avatar's physical shape becomes about half of the avatar's height. But if you don't account for the height offset, it'll seem like "your legs get shorter." You can offset the bounding box by the avatar's height. (divided by 4, which is half-of-half or 25%)

Here's a script you can use to visualize what happens between "avatar size" and "bounding box":
(Rez 2 transparent cubes and link them together before putting this script in it. Then wear the cubes on Avatar Center.)

default
{
    timer()
    {
        list data = llGetBoundingBox(llGetOwner());
        vector bb = llList2Vector(data,1) - llList2Vector(data,0);
        // llOwnerSay(llDumpList2String(data, ", "));
        // llOwnerSay("bounding box: " + (string)bb);
        
        vector size = llGetAgentSize(llGetOwner());
        // llOwnerSay("agent size: " + (string)size);
        
        llSetLinkPrimitiveParamsFast(1, [
            PRIM_SIZE, size,
            PRIM_LINK_TARGET, 2,
            PRIM_SIZE, bb,
            // This will account for the avatar's bounding box while sitting:
            PRIM_POSITION, (<0,0,-size.z> * 0.25)
        ]);
    }
    
    state_entry()
    {
        llSetTimerEvent(1);
        
        if(llGetAttached())
        {
            llSetLinkPrimitiveParamsFast(-1, [PRIM_POSITION, ZERO_VECTOR]);
        }
    }
    
    attach(key id)
    {
        if(id)
        {
            llSetLinkPrimitiveParamsFast(-1, [PRIM_POSITION, ZERO_VECTOR]);
        }
    }
}

 

Edited by Wulfie Reanimator
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 2338 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...