Feedback

Please leave feedback and comments. I am always interested to hear how people get on using these LScripts!

Monday, 18 February 2013

LScript - Generic_BoxRig (v1.1)

LScript (Layout) to rig a box so that it can pivot upon its edges and corners. This script sets up the hiearchy and expressions required ready for animation upon any selected objects.

Use "Parent" null to position and rotate box and "Control" null to animate using the rig.

Problem
  • Under LightWave 11 Item Shape is broken due to changes in comring
Changes
  • Fixed parenting (v1.1)
  • Objects require pivot to be resting on ground and centre of object
  • Does not work on clones due to expressions
  • Fixed getting correct boundingbox extents from layers
  • Fixed Parent in Place issues
  • Fixed offset when pivot not at bottom of object
Compatible with Newtek LightWave 9.6 up and prior to 11.0.

// LScript Generic - www.StephenCulley.co.uk
//
// web   address: http://www.stephenculley.co.uk
// email address: email@stephenculley.co.uk

/*  
    LScript Generic - BoxRig

    Generic_BoxRig.ls

*/

@version 2.2
@warnings
@script generic
@name *Box Rig
  
    // Title
    sTitle = "*Box Rig";

    // Version
    sVersion = "v1.1";    

generic
{

    // Item Select
    Items = Scene().getSelect();  
    if(Items == nil)
      {
      info("Select an object.");
      return;
      }

    // Parent in Place
    bParentInPlace = Scene().generalopts[3];
    if(bParentInPlace){ParentInPlace();}

    for(i = 1; i <= Items.size(); i++)
      {

      if(Items[i].genus == MESH && !Items[i].null)
        {

        GoToFrame(0);

        SelectItem(Items[i].id);
 
        // Box Item
        BoxItem = Mesh(0); // Get Box
        BoxItem_Parent = BoxItem.parent; // Parent
        vPivot = BoxItem.getPivot(0.0);
        vPosition = BoxItem.getPosition(0.0); // Position
        vRotation = BoxItem.getRotation(0.0); // Rotation
        vScaling = BoxItem.getScaling(0.0); // Scaling
        aBoundingBox = BoxItem.position(getlayernumber(BoxItem)); // Bounding Box
        aBoundingBox[1] -= vPivot; 
        aBoundingBox[2] -= vPivot;

        sName = BoxItem.name; // Name

        // Reset Box
        Position(0.0,-aBoundingBox[1].y,0.0);
        Rotation(0.0,0.0,0.0);
        Scale(1.0,1.0,1.0);
        CreateKey(0);

        // Parent Item
        AddNull(sName + "_Parent");
        ParentItem = Mesh(sName + "_Parent"); // Assign to a var       
        ItemColor(12); // Color Dark Red
        Position();
        Rotation(vRotation);
        Scale(vScaling);
        CreateKey(0);
        if(BoxItem_Parent != nil){ParentItem(BoxItem_Parent.id);} // Parent

        // Pivot Item
        AddNull(sName + "_Pivot");
        PivotItem = Mesh(sName + "_Pivot"); // Assign to a var
        ItemColor(5); // Color Dark Red
        ParentItem(ParentItem.id); // Parent

        // Shift Item
        AddNull(sName + "_Shift");
        ShiftItem = Mesh(sName + "_Shift"); // Assign to a var
        ItemColor(5); // Color Dark Red
        ParentItem(PivotItem.id); // Parent
        MoveTool();
        EnableXH();
        EnableYP();
        EnableZB();
        RotateTool();
        EnableXH();
        EnableYP();
        EnableZB();
        SquashTool();
        EnableXH();
        EnableYP();
        EnableZB();

        // Box Item
        BoxItem.select();
        ParentItem(ShiftItem.id); // Parent
        ItemColor(7); // Color Brown
        MoveTool();
        EnableYP();
        RotateTool();
        EnableYP();
        EnableZB();
        SquashTool();
        EnableXH();
        EnableYP();
        EnableZB();

        // Extent Item
        AddNull(sName + "_Extent");
        ExtentItem = Mesh(sName + "_Extent"); // Assign to a var
        ItemColor(5); // Color Dark Red
        ParentItem(ParentItem.id); // Parent
        Position(aBoundingBox[2].x,0.0,aBoundingBox[2].z);
        CreateKey(0);
        MoveTool();
        EnableYP();
        RotateTool();
        EnableXH();
        EnableYP();
        EnableZB();
        SquashTool();
        EnableXH();
        EnableYP();
        EnableZB();

        // Control Item
        AddNull(sName + "_Control");
        ControlItem = Mesh(sName + "_Control"); // Assign to a var
        ItemColor(12); // Color Red
        ParentItem(ParentItem.id); // Parent
        MoveTool();
        EnableYP();
        RotateTool();
        EnableYP();
        EnableZB();
        SquashTool();
        EnableXH();
        EnableYP();
        EnableZB();

        // Custom
        customshape(ParentItem,nil,0,nil,"Parent");
        customshape(PivotItem,ParentItem,8,nil,"Pivot");
        customshape(ShiftItem,ParentItem,8,nil,"Shift");
        customshape(BoxItem,ParentItem,8,nil,"");
        customshape(ExtentItem,ParentItem,8,nil,"Extent");
        customshape(ControlItem,ParentItem,6,0.15,"Control");

    // EXPRESSIONS

        // Shift_X
        createexpression(sName + "_Shift_X","max(min((( - ([" + sName + "_Control.Position.X] * 1000) ) * (1 / 5)) * (  [" + sName + "_Extent.Position.X]  ),[" + sName + "_Extent.Position.X]),-[" + sName + "_Extent.Position.X])");
        ShiftItem.select();
        attachexpression(sName + "_Shift_X",sName + "_Shift.Position.X");

        // Shift_Z
        createexpression(sName + "_Shift_Z","max(min((( - ([" + sName + "_Control.Position.Z] * 1000) ) * (1 / 5)) * (  [" + sName + "_Extent.Position.Z]  ),[" + sName + "_Extent.Position.Z]),-[" + sName + "_Extent.Position.Z])");
        ShiftItem.select();
        attachexpression(sName + "_Shift_Z",sName + "_Shift.Position.Z");

        // Pivot_X
        createexpression(sName + "_Pivot_X","min(max((( - ([" + sName + "_Control.Position.X] * 1000) ) * (1 / 5)) * (  -[" + sName + "_Extent.Position.X]  ),-[" + sName + "_Extent.Position.X]),[" + sName + "_Extent.Position.X])");
        PivotItem.select();
        attachexpression(sName + "_Pivot_X",sName + "_Pivot.Position.X");

        // Pivot_Z
        createexpression(sName + "_Pivot_Z","min(max((( - ([" + sName + "_Control.Position.Z] * 1000) ) * (1 / 5)) * (  -[" + sName + "_Extent.Position.Z]  ),-[" + sName + "_Extent.Position.Z]),[" + sName + "_Extent.Position.Z])");
        PivotItem.select();
        attachexpression(sName + "_Pivot_Z",sName + "_Pivot.Position.Z");

        // Pivot_H
        createexpression(sName + "_Pivot_H","[" + sName + "_Control.Rotation.H]");
        PivotItem.select();
        attachexpression(sName + "_Pivot_H",sName + "_Pivot.Rotation.H");

        // Pivot_P
        createexpression(sName + "_Pivot_P","mapRange([" + sName + "_Control.Position.Z],0.000,[" + sName + "_Extent.Position.Z],0.000,90.000)");
        PivotItem.select();
        attachexpression(sName + "_Pivot_P",sName + "_Pivot.Rotation.P");

        // Pivot_B
        createexpression(sName + "_Pivot_B","- mapRange([" + sName + "_Control.Position.X],0.000,[" + sName + "_Extent.Position.X],0.000,90.000)");
        PivotItem.select();
        attachexpression(sName + "_Pivot_B",sName + "_Pivot.Rotation.B");

    //

        // Control
        ControlItem.select();
        MoveTool();

        }

      }

    // Parent in Place
    if(bParentInPlace){ParentInPlace();}

    info(sTitle + " " + sVersion + " - developer: Stephen Culley - http://www.stephenculley.co.uk");
}

getlayernumber: item
{
    if(item.totallayers == 1){return(1);}
    sTokens = parse(":",item.name);
    iLayer = 0;
    if (strleft(sTokens[2],5)=="Layer")
      {
      iLayer = integer(sTokens[2]);
      }
    else
      {
      iTotal = item.totallayers;
      for(i = 1; i <= iTotal; i++)
        {
        if(item.layerVisible(i) == 1)
          {
          if(item.layerName(i) == sTokens[2])
            {
            iLayer = i;
            break;
            }
          }
        else
          {
          iTotal++;
          }
        }
      }
  return iLayer;
}

createexpression: name, expression
{
    CommandInput("GE_CreateExpression " + "\"" + name + "\"" + " " + "\"" + expression + "\"");
} 

attachexpression: name,channel
{
    CommandInput("GE_OpenWindow");
    CommandInput("GE_SetEnv " + "\"" + channel);
    CommandInput("GE_AttachExpression " + "\"" + channel + "\"" + name);
}

customshape: item,linkto,shape,scale,label
{
    SelectItem(item.id);
    ApplyServer("CustomObjHandler","LW_ItemShape");

    // ItemShapeData structure
    aItemShapeData = @"p",                // ctxt
                      "p","p",            // self, linkTo
                      "d","d","d",        // time, level, scale
                      "i","i","i","i",    // axis, fill, shape, flags
                      "f","f","f",        // clrA
                      "f","f","f",        // clrB
                      "f","f","f",        // clrT
                      "d","d","d",        // linkPos
                      "s:120",            // label
                      "s:100",            // desc
                      "p",                // alreadylist
                      "s:256",            // selfname
                      "s:256",            // linktoname
                      "i"@;               // justify
                    
    comringattach("ItemShapeComRing", "shapecomring");
    aDataBlob = comringencode(aItemShapeData,
                              0,
                              item.id, 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);

    comringmsg("ItemShapeComRing", 100, aDataBlob);
    aItemShape = comringdecode(aItemShapeData, aDataBlob);
    if(linkto != nil){aItemShape[3] = linkto.id;}    // linkto
    if(scale != nil){aItemShape[6] = scale;}    // Scale
    aItemShape[7] = 1;    // Axis
    aItemShape[9] = shape;    // Shape
    aItemShape[23] = label; // Label
    if(linkto != nil)
        aItemShape[27] = linkto.name;  // linkto name
    aDataBlob = comringencode(aItemShapeData,
                                aItemShape[1],
                                aItemShape[2],aItemShape[3],
                                aItemShape[4],aItemShape[5],aItemShape[6],
                                aItemShape[7],aItemShape[8],aItemShape[9],aItemShape[10],
                                aItemShape[11],aItemShape[12],aItemShape[13],
                                aItemShape[14],aItemShape[15],aItemShape[16],
                                aItemShape[17],aItemShape[18],aItemShape[19],
                                aItemShape[20],aItemShape[21],aItemShape[22],
                                aItemShape[23],
                                aItemShape[24],
                                aItemShape[25],
                                aItemShape[26],
                                aItemShape[27],
                                aItemShape[28]);
    comringmsg("ItemShapeComRing", 200, aDataBlob);
    comringdetach("ItemShapeComRing");
}

shapecomring: code, data
{
}


All scripts available at my Google Drive at
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs

No comments:

Post a Comment