User:Dz/Avatar Scale

From OpenSimulator

< User:Dz
Revision as of 11:22, 21 September 2014 by Dz (Talk | contribs)

Jump to: navigation, search

Contents

Avatar Scale

This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator. With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue experimenting and improving this important skill.

Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.

As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.

The scale relies on the ability to move a seated avatar via script. This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release. It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.

If you have feedback on script errors, please post it to the page discussion User_talk:Dz/Avatar Scale


The script

I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it. Read the comments for information about use and distribution..

//  Avatar proportion scale   BETA
//  based on an "8 head" (Natural) or "9 head" (Heroic) human shape
 
// Doug Osborn   MOSES grid   9/17/2014
// Copyright (c) 2014, Douglas Osborn
// All rights reserved.
 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
 
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer. 
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
//
//   To create your own scale from scratch,  
//      Make a cube to act as your base.  Texture it as you like and turn it phantom.
//      Make 9 more cubes and stack them on top of each other.   
//      Link the 9 cubes together and then link that stack to your "base" cube
//      Copy the [CheckPorportions] animation and the [Proportional Avatar Sizing} notecard into the base
//      Drop this script into your base cube. 
//      Your stack of cubes should transform into a "Natural" scale for a 2 meter avatar
//
//
 
vector MyLocation = <0,0,0>;
rotation MyRotation = ZERO_ROTATION;
 
list offsetMultiplier = [1,3,5,7,9,11,13,15,17];
 
string ANIMATION = "CheckProportions";
 
key avatar = NULL_KEY;
list menuButtons = ["Heroic","Natural","Set Height"]; 
list heightButtons = [ "Move Up", "Move Down"];
integer menuchannel = -13572468;
integer heightchannel = -13572469;
integer mListener = 0;
integer cListener = 0;
float sitTargetHeight = 0;
integer NaturalMode = TRUE;
string menuStatusInfo = "";
float currentScaleSize = 2.0;
float menuTimeout = 30.0;
vector primColor = <0.0, 0.0, 0.0>;
float panelDivisor = 4.0;
float widthAdjust = 0.02;
 
setScaleDimensions(float newSize)
{
    integer numlinks = 11;
    panelDivisor = 4.5;
    widthAdjust = 0.05;
 
    if (NaturalMode)
    {
        numlinks = 10;
        panelDivisor = 4;
        widthAdjust = -0.025;
    }
 
    llSay(0, "Resizing scale for a  " +(string) newSize + " meter avatar");
 
    currentScaleSize = newSize;
 
    sitTargetHeight = newSize/2.3;
 
    llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));
 
    integer link = 2;
    while (link < numlinks)
    {
        float heightOffset = (llList2Integer(offsetMultiplier,link-2) * (newSize/(panelDivisor * 4)));
        if (link%2 == 0)
        { 
            primColor = <0.75, 0.75, 0.75>;
        }
        else
        {
            primColor = <0.0, 0.0, 0.0>;
        }            
 
        llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, 
                                                    PRIM_POS_LOCAL,<0.0 , 0.0, heightOffset>,
                                                    PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE,
                                                    PRIM_COLOR, ALL_SIDES, primColor, 0.5 ]);
        link ++;
    } 
 
    if (NaturalMode)
    {
        llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, 
                                                    PRIM_POS_LOCAL,<0.0 , 0.0, 0.0>,
                                                    PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE, 
                                                    PRIM_COLOR, ALL_SIDES, primColor, 0.0]);
    }       
}
 
default
{
    state_entry()
    {
        llSay(0, "OpenSimian Avatar scale is ready to use");
        MyLocation = llGetRootPosition(); 
        MyRotation = llGetRootRotation(); 
        setScaleDimensions(currentScaleSize);      
    }
 
    touch_start(integer numTouches)
    {
        string mode = "Heroic";
        if(NaturalMode)
            mode = "Natural";
 
        menuStatusInfo = "\nCurrent mode : " + mode + "\nAvatar height: " + llGetSubString((string) currentScaleSize, 0, 4) +"(meters)\n \nMake a selection";      
 
        if (avatar != NULL_KEY)
        {
            cListener = llListen( heightchannel, "", "", ""); 
            llDialog(llDetectedKey(0), menuStatusInfo,  heightButtons, heightchannel);
            llSetTimerEvent(menuTimeout); 
        } 
        else
        { 
            mListener = llListen( menuchannel, "", "", "");       
            llDialog(llDetectedKey(0), menuStatusInfo,  menuButtons, menuchannel);
            llSetTimerEvent(menuTimeout);
        }     
    }
 
    listen(integer channel, string name, key id, string message)
    {
        if(channel == menuchannel)
        {
            llListenRemove(mListener);
            llSetTimerEvent(0);
 
            if (message == "Heroic")
            {
                if ( NaturalMode )
                {
                    NaturalMode = FALSE;
                    llSay(0,"Resetting to Heroic Mode");
                    setScaleDimensions(currentScaleSize);    
                }
                else
                {
                    llSay(0,"Already in Heroic Mode");
                }
            }
 
            if (message == "Natural")
            {
                if ( NaturalMode )
                {
                    llSay(0,"Already in Natural Mode");
                }
                else
                {
                    NaturalMode = TRUE;
                    llSay(0,"Resetting to Natural Mode");
                    setScaleDimensions(currentScaleSize);    
                }
            }            
 
            if (message == "Set Height")
            {
                cListener = llListen( heightchannel, "", "", ""); 
                llTextBox(id, "Enter the total Height of the avatar in METERS", heightchannel);
            }
            if (message == "Move Up")
            {
                sitTargetHeight += .025;
                llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); 
                mListener = llListen( menuchannel, "", "", "");         
                llDialog(id, "Select an Option",  heightButtons, menuchannel);                  
            }
            if (message == "Move Down")
            {
                sitTargetHeight -= .025;
                llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); 
                mListener = llListen( menuchannel, "", "", "");         
                llDialog(id, "Select an Option",  heightButtons, menuchannel);                  
            }
        }            
        if(channel== heightchannel)
        {
            llListenRemove(cListener);
            setScaleDimensions((float) message);          
        }
    }
 
    changed(integer change) 
    {
        if(change & CHANGED_LINK) 
        {
            avatar = llAvatarOnSitTarget();
            if(avatar != NULL_KEY)
            {
                llRequestPermissions(avatar,  PERMISSION_TRIGGER_ANIMATION);
            }
            else
            {
                if (llGetPermissionsKey() != NULL_KEY)
                { 
                    llStopAnimation(ANIMATION); 
                    llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));
                    avatar = NULL_KEY;
                }
            }
        }
        if(change & CHANGED_INVENTORY) { llResetScript(); }
        if(change & CHANGED_OWNER)     { llResetScript(); }
    }
 
 
    run_time_permissions(integer perm) 
    {
        if(perm & PERMISSION_TRIGGER_ANIMATION) {
            llStopAnimation("sit");
            llStartAnimation(ANIMATION);
            mListener = llListen( menuchannel, "", "", "");         
            llDialog(avatar, "Select an Option",  heightButtons, menuchannel);    
        }
    }
 
    timer()
    {
        llSay(0, "Menu selection time limit ( 30 seconds ) exceeded, please touch the scale again for a new menu");
        llListenRemove(mListener); 
        llSetTimerEvent(0);
    }
}

CheckProportions BVH file

This is a very basic animation that stands the avatar upright with feet together and hands hanging down. It is a close enough match to the references included in the note card. You should be able to upload this file as an animation file and use it with most avatar models that the scale is appropriate for. The script expects the uploaded animation to be named "CheckProportions". Feel free to change it, but then you will also need to change the script.

I recommend that you set the animation priority to 4 and set the animation to LOOP when uploaded. This will help insure it remains active while the avatar is on the scale.

HIERARCHY
ROOT hip
{
    OFFSET    0.00  0.00  0.00 
    CHANNELS 6 Xposition Yposition Zposition Xrotation Zrotation Yrotation
    JOINT abdomen
    {
        OFFSET    0.000000 3.422050 0.000000
        CHANNELS 3 Xrotation Zrotation Yrotation
        JOINT chest
        {
            OFFSET    0.000000 8.486693 -0.684411
            CHANNELS 3 Xrotation Zrotation Yrotation
            JOINT neck
            {
                OFFSET    0.000000 10.266162 -0.273764
                CHANNELS 3 Xrotation Zrotation Yrotation
                JOINT head
                {
                    OFFSET    0.000000 3.148285 0.000000
                    CHANNELS 3 Xrotation Zrotation Yrotation
                    End Site
                    {
                        OFFSET 0.000000 3.148289 0.000000
                    }
                }
            }
            JOINT lCollar
            {
                OFFSET    3.422053 6.707223 -0.821293
                CHANNELS 3 Yrotation Zrotation Xrotation
                JOINT lShldr
                {
                    OFFSET    3.285171 0.000000 0.000000
                    CHANNELS 3 Zrotation Yrotation Xrotation
                    JOINT lForeArm
                    {
                        OFFSET    10.129278 0.000000 0.000000
                        CHANNELS 3 Yrotation Zrotation Xrotation
                        JOINT lHand
                        {
                            OFFSET    8.486692 0.000000 0.000000
                            CHANNELS 3 Zrotation Yrotation Xrotation
                            End Site
                            {
                                OFFSET 4.106464 0.000000 0.000000
                            }
                        }
                    }
                }
            }
            JOINT rCollar
            {
                OFFSET    -3.558935 6.707223 -0.821293
                CHANNELS 3 Yrotation Zrotation Xrotation
                JOINT rShldr
                {
                    OFFSET    -3.148289 0.000000 0.000000
                    CHANNELS 3 Zrotation Yrotation Xrotation
                    JOINT rForeArm
                    {
                        OFFSET    -10.266159 0.000000 0.000000
                        CHANNELS 3 Yrotation Zrotation Xrotation
                        JOINT rHand
                        {
                            OFFSET    -8.349810 0.000000 0.000000
                            CHANNELS 3 Zrotation Yrotation Xrotation
                            End Site
                            {
                                OFFSET -4.106464 0.000000 0.000000
                            }
                        }
                    }
                }
            }
        }
    }
    JOINT lThigh
    {
        OFFSET    5.338403 -1.642589 1.368821
        CHANNELS 3 Xrotation Zrotation Yrotation
        JOINT lShin
        {
            OFFSET    -2.053232 -20.121670 0.000000
            CHANNELS 3 Xrotation Zrotation Yrotation
            JOINT lFoot
            {
                OFFSET    0.000000 -19.300380 -1.231939
                CHANNELS 3 Xrotation Yrotation Zrotation
                End Site
                {
                    OFFSET 0.000000 -2.463878 4.653993
                }
            }
        }
    }
    JOINT rThigh
    {
        OFFSET    -5.338403 -1.642589 1.368821
        CHANNELS 3 Xrotation Zrotation Yrotation
        JOINT rShin
        {
            OFFSET    2.053232 -20.121670 0.000000
            CHANNELS 3 Xrotation Zrotation Yrotation
            JOINT rFoot
            {
                OFFSET    0.000000 -19.300380 -1.231939
                CHANNELS 3 Xrotation Yrotation Zrotation
                End Site
                {
                    OFFSET 0.000000 -2.463878 4.653993
                }
            }
        }
    }
}
MOTION
Frames:     1
Frame Time: 0.5
0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

Information Notecard

This is an optional add-on. It is not required, but I have included it to help explain the use to a novice user. I recommend that you at least READ through the note card before you attempt to use the scale for yourself. If you intend to re-distribute the scale, Please Please Please include this or something like it to minimize the support questions that may result.

This is a BETA implementation of an avatar sizing scale
It is designed to provide a simple scale with which you can measure the proportions of your avatar.
 
There are 2 scale modes enabled.  
The default  "Natural" mode is based on a  8 head scale. 
Realistic human avatars should be approximately 8 heads tall,  and just under 2 heads  wide.
 
It also supports a "Heroic" mode based on a 9 head scale.  
Heroic avatars will have longer legs and should be wider at both the shoulders and hips.  
There are some studies that show this is considered more attractive in many western cultures.
 
The scale has alternating Dark and Light "bars" in it to help you see the important locations..
 
To use the scale,  place it on a flat surface so that the base of the scale is close to the surface but not beneath it.
Touch the scale and use the menu buttons to set the mode you desire (Default is Natural) , or select the [SET Height]  button.
Enter the desired avatar  height ( in METERS) in the text box ( without hitting return,  Use the submit button...).  
 
The scale should adjust its configuration or size and give you a message as it does so.
 
DO NOT SIT ON THE SCALE UNTIL YOU HAVE SET THE PROPER MODE AND SIZE
The scale will attempt to "guess" at, and set, a proper sit location.  This will NOT work if you are already sitting..
 
Once the scale has reset you can sit on the scale.  There is an animation provided to pose you appropriately. 
You should be positioned in the middle of the base with the scale running up the middle of your avatar.
Your feet should be close to the ground. 
 
Touch the scale again and use the {Move Up] or {Move Down] buttons to adjust your position until your feet are on the base.
( Note)  this BETA version of the scale has issues and you may see your avatar JUMP the first time you try to adjust.
 
*********************************************
 
What you SHOULD see if your "Natural" avatar is correctly proportioned
 
The first (top) bar should go from the top of your head to the bottom of your chin.
Your shoulders should be approximately the same width as the scale.
Male nipples should be slightly above or at the bottom of the second bar.
Female nipples should be slightly below the bottom of the second bar.
Your "belly button" should be just under the third bar.
Your crotch should be at the bottom of the fourth bar, 1/2 way down.
Your wrists should also be in approximately the same place,  1/2 way down.
Your knees should be above the 6th bar,  at least 2 bars above the ground.
Your Feet should be on the base.
 
When using "Heroic" mode the following adjustments should be made..
Both Male and Females nipples should appear just under the bottom of the second bar.
Male crotch should be 1/4 - 1/3 of the way down from the top of the 5th bar.
Knees should be under, instead of above, the bottom of the 6th bar.
 
*******************************************
Unfortunately, you will not be able to make avatar size adjustments while sitting on the scale.
To adjust body size, you must stand,  use [edit appearance] to make changes, and sit on the scale again to check.
The scale is supposed to remember the adjustments you made, but you may have to adjust it again ( its BETA)
********************************************
 
As a rough guide,  the following  appearance parameters can be modified to achieve the best "fit"
 
   In the BODY section,  use the HEIGHT slider.
 
   In the HEAD section, first use the HEAD SIZE slider, and then the HEAD STRETCH
       ( you may want to play with the CHIN section  sliders, but I recommend you come back to those later)
 
   In the TORSO section,   Use SHOULDERS to set the shoulder width.  
       (Muscular torsos will extend beyond the scale slightly)
       Use the ARM LENGTH slider to position your wrists
       Use the TORSO LENGTH slider to move your belly
 
   In the LEGS section, use LEG LENGTH to adjust the position of your knees and get your feet on the ground.
       Adjust HIP LENGTH to modify your belly button and crotch locations.  
 
 
************************************************

Here are some web references to help you visualize the "landmarks" provided by the scale...
 
    http://www.idrawdigital.com/2009/01/drawing-tutorial-anatomy-and-proportion-1/
 
    http://www.3dhaze.com/tutorials/char_model/proportions.html
 
    http://www.pinterest.com/lillegerd/human-proportions/
 
    http://hpc.anatomy4sculptors.com/
Personal tools
General
About This Wiki