# Need Help Positioning Child Prim

## Recommended Posts

Hi All,

Have what I hope is an easy question, though I have tried a number of different methods and not been able to find an answer. I have two prims, linked. When I click on the parent prim it runs through a routine the gradually reduces its Z scale, adjusting its height so that the top of the prim remains fixed (to simulate the opening of window blinds). when these are done moving I want the child prim to be back flush to the bottom of the prim, and this is the part that I cannot get.

Any suggestions?

##### Share on other sites

What do you have so far?

This is a simple question about calculating the child's positions from the scale of the root prim and the scale of the child prim.

Isn't it?:smileyhappy:

##### Share on other sites

Here is a little example - I think it may be easier than lengthy explanations.

`integer giUp =0;vector sizer;default{    state_entry() {        sizer = llList2Vector(llGetLinkPrimitiveParams(1, [PRIM_SIZE]), 0);    }    touch_end(integer num_detected) {                        vector pos = llList2Vector(llGetLinkPrimitiveParams(1, [PRIM_POSITION]), 0);            vector posc = llList2Vector(llGetLinkPrimitiveParams(2, [PRIM_POSITION]), 0);            vector posrel = posc - pos;            if (!giUp) {                llSetLinkPrimitiveParamsFast(1, [PRIM_SIZE, <sizer.x, sizer.y, sizer.z/2>, PRIM_POSITION, <pos.x, pos.y, pos.z + sizer.z/4>]);                llSetLinkPrimitiveParamsFast(2, [PRIM_POSITION, <posrel.x, posrel.y, posrel.z + sizer.z/4>]);            }  else {                llSetLinkPrimitiveParamsFast(1, [PRIM_SIZE, <sizer.x, sizer.y, sizer.z>, PRIM_POSITION, <pos.x, pos.y, pos.z - sizer.z/4>]);                llSetLinkPrimitiveParamsFast(2, [PRIM_POSITION, <posrel.x, posrel.y, posrel.z - sizer.z/4>]);            }            giUp = !giUp;    }}`

That could be a window blind with a prim flush with the bottom of it.

##### Share on other sites

Thanks Darkie .. I'll give it a try .. and that is precidely what I need it for .. window blinds with a bottom flush prim :matte-motes-big-grin:

##### Share on other sites

Great, with Darkie's help got this working perfectly ... and to give back a bit to the forum, the following is the resulting code that allows for a window blind to move up and down:

`//`
`////// *******************************************************************// This program is free software; you can redistribute it and/or// modify as you wish. Just don't try and sell it to someone ...// that would not be nice or fair.//// While I do not offer support for this script if you have questions// feel free to contact me inworld.//// Writen by Wandering Soulstar// *******************************************************************//######//Constants//Set per blindfloat MAX_HEIGHT = 4.4;float MAX_TEXT_V = 2.0;//Specific percentage for a fully opened blindfloat FULL_OPEN = 0.04;//Step change as it movesfloat ADJ_PERC = 0.02;//Flag if we have a linked priminteger CHILD_PRIM = TRUE;//Flag if we listen to a global controllerinteger GLOBAL_CONTROLLER = TRUE;//Flag if we limit to only the ownerinteger OWNER_ONLY = TRUE;//Channelsinteger COMMS_CH = -501000;integer DIAG_CH = -600000;//Texture Keys .. if only one, set to the same valuestring OPEN_TEXT = "";string CLOSED_TEXT = "";//These constants should nt be changed//Actionsstring OPEN = "OPEN";string CLOSED = "CLOSED";string LOCAL = "LOCAL";//End Constants//......//######//Variables//Used to build results from Menusstring gBlindState = "";//User who has touched for a menukey gUserKey = NULL_KEY;//End Variables//......//######//Functions//Principal workoing functionset_blind(string params, integer isGlobal){    list dataVals = llParseString2List(params, ["^"], [""]);    string action = llList2String(dataVals, 0);    string subAction;    string text;    float adj;    //What have we benn asked to do?    //LOCAL,CLOSED,OPEN,%;Texture    if (action == OPEN)    {        //Texture is closed        text = CLOSED_TEXT;        adj = FULL_OPEN;    }    else if (action == LOCAL)    {        //Read the values from my desc        string desc = llGetObjectDesc();        dataVals = llParseString2List(desc, ["^"], [""]);        //First is texture, second if %        text = llList2String(dataVals, 0);        adj = llList2Float(dataVals, 1);    }    else    {        if (action == CLOSED)        {            adj = 1.0;        }        else        {            adj = (float)action/100;        }                        //Now read in the second value, tells us which texture        subAction = llList2String(dataVals, 1);        if (subAction == OPEN)        {            text = OPEN_TEXT;        }        else        {            text = CLOSED_TEXT;        }    }    //Now do the work    //Set Texture    llSetTexture(text, ALL_SIDES);    //Get current values    vector sizeBlind = llGetScale();    vector posBlind = llGetPos();    vector texScale = llGetTextureScale(ALL_SIDES);    //Get new Size    float newSize = MAX_HEIGHT * adj;    integer dirMod;    //Check what direction    if (newSize < sizeBlind.z)    {        dirMod = -1;    }    else if (newSize > sizeBlind.z)    {        dirMod = 1;    }    float incrS = (MAX_HEIGHT * ADJ_PERC) * dirMod;    float incrH = (MAX_HEIGHT * ADJ_PERC)/(-2 * dirMod);    float incrT = (MAX_TEXT_V * ADJ_PERC) * dirMod;    while (sizeBlind.z != newSize)    {        //Calculate values        sizeBlind.z = sizeBlind.z + incrS;        posBlind.z = posBlind.z + incrH;        texScale.y = texScale.y + incrT;        //Check if we have gone past the target size        if ((sizeBlind.z  > newSize && incrS > 0) || (sizeBlind.z  < newSize && incrS < 0))        {            sizeBlind.z = newSize;        }        vector posRelation;        //This is if we have a linked child prim to the blind to adjust its position        if (CHILD_PRIM == TRUE)        {            posRelation = llList2Vector(llGetLinkPrimitiveParams(2, [PRIM_POSITION]), 0) - posBlind;            posRelation.z = posRelation.z - incrS;        }        //Do the change        llSetLinkPrimitiveParamsFast(LINK_ROOT, [PRIM_SIZE, sizeBlind, PRIM_POSITION, posBlind]);        if (CHILD_PRIM == TRUE)        {            llSetLinkPrimitiveParamsFast(2, [PRIM_POSITION, posRelation]);        }        llScaleTexture(texScale.x, texScale.y, ALL_SIDES);    }    //Set values to my Desc if this was not a global call    if (isGlobal == FALSE)    {        llSetObjectDesc(text + "^" + (string)adj);    }}//End Functions//......//Bodydefault{    state_entry()    {        if (GLOBAL_CONTROLLER == TRUE)        {            //Listen from a call from the controler            llListen(COMMS_CH, "", NULL_KEY, "");        }    }//End state_entry    listen(integer channel, string name, key id, string message)    {        //Call from the global controller        //Messages in the same format as menus, just has another option 'Local'        //this option tells th eblind to go back to th elast value that was set        //by a user clicking on it        set_blind(llToUpper(message), TRUE);    }//End listen    touch_end(integer total_number)    {        //Show the Menu        gUserKey = llDetectedKey(0);        //Check if owner flag set ...        if((OWNER_ONLY == TRUE && gUserKey == llGetOwner()) || OWNER_ONLY == FALSE)        {            state menu_start;        }    }//End_touch}//End defaultstate menu_start{    state_entry()    {        //send the first Menu        llListen(DIAG_CH, "", gUserKey, "");        llDialog(gUserKey, "Select the % height of the blinds", [ "50", "70", "80", "10", "20", "30","Open", "Closed"], DIAG_CH);        llSetTimerEvent(30.0);    }//End state_entry    listen(integer channel, string name, key id, string message)    {        message = llToUpper(message);        gBlindState = message;        if (message == OPEN)        {            set_blind(message, FALSE);            state default;        }        else        {            state menu_angle;        }    }//End listen    timer()    {        state default;    }//End timer    state_exit()    {        llSetTimerEvent(0.0);    }//End state_exit}//End menu_startstate menu_angle{    state_entry()    {        //send the angle (texture) Menu        llListen(DIAG_CH, "", gUserKey, "");        llDialog(gUserKey, "Do you want the blind angle Open or Closed?", ["Open", "Closed"], DIAG_CH);        llSetTimerEvent(30.0);    }//End state_entry    listen(integer channel, string name, key id, string message)    {        set_blind(gBlindState + "^" + llToUpper(message), FALSE);        state default;    }//End listen    timer()    {        state default;    }//End timer    state_exit()    {        llSetTimerEvent(0.0);    }//End state_exit}//End menu_angle//`

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.