Feedback

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

Wednesday, 18 December 2013

LScript - Motion_Squash


LScript (Layout) to squash objects based on interaction with ground plane. I use it for quick ball animations to squash as they bounce.

Compatible with Newtek LightWave 9.6 and above.

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

/* 
    LScript Item Animation - Squash

    Motion_Squash.ls

*/

@version 2.2
@warnings
@script motion
@name *Squash

    // Title
    sTitle = "*Squash";

    // Version
    sVersion = "v1.0";

    // Item
    GroundItem = nil; // Item
    GroundItemName = "nil"; // Item

    // Variable
    bWorldCoordinates = false;
    nRadius = 1.0;
    nStretchX = 0.33;
    nStretchZ = 0.33;

create
{
    // Description
    setdesc(sTitle);

    // Info
    info("*Squash - Apply a scaling effect based on Y axis.");
}

destroy
{
}

process: ma, frame, time
{     
    // Variables
    if(bWorldCoordinates) 
      {
      vPosition = ma.get(WPOSITION,time);
      vRotation = ma.get(ROTATION,time);
      vScale = ma.get(SCALING,time);
      vGroundItemPosition = <0,0,0>;
      vGroundItemRotation = <0,0,0>;
      vGroundItemScale = <0,0,0>;

      if(GroundItemName != "nil") {GroundItem = Mesh(GroundItemName); GroundItemName = "nil";}
      if(GroundItem)
        { 
        vGroundItemPosition = GroundItem.getWorldPosition(time);
        vGroundItemRotation = GroundItem.getRotation(time);
        vGroundItemScale = GroundItem.getScaling(time);
        }
      else
        {
        Item = ma.objID;
        ItemParent = Item.parent;
        if(ItemParent)
          {
          vGroundItemPosition = ItemParent.getWorldPosition(time);
          vGroundItemRotation = ItemParent.getRotation(time);
          vGroundItemScale = ItemParent.getScaling(time);
          }
        }

      }
    else
      {
      vPosition = ma.get(POSITION,time);
      vRotation = ma.get(ROTATION,time);
      vScale = ma.get(SCALING,time);
      vGroundItemPosition = <0,0,0>;
      vGroundItemRotation = <0,0,0>;
      vGroundItemScale = <0,0,0>;

      if(GroundItemName != "nil") {GroundItem = Mesh(GroundItemName); GroundItemName = "nil";}
      if(GroundItem)
        { 
        vGroundItemPosition = GroundItem.getPosition(time);
        vGroundItemRotation = GroundItem.getRotation(time);
        vGroundItemScale = GroundItem.getScaling(time);
        }
      else
        {
        Item = ma.objID;
        ItemParent = Item.parent;
        if(ItemParent)
          {
          vGroundItemPosition = ItemParent.getPosition(time);
          vGroundItemRotation = ItemParent.getRotation(time);
          vGroundItemScale = ItemParent.getScaling(time);
          }
        }

      }
        
  nDistance =  abs(vGroundItemPosition.y - vPosition.y);
  if(nDistance < nRadius)
    {
    // Squash
    nScale = (1 / nRadius) * nDistance;
    vScale.y := nScale;
    // Stretch
    vScale.x = 1 + ((1 - nScale) * nStretchX);
    vScale.z = 1 + ((1 - nScale) * nStretchZ);
    }

// ma

  ma.set(SCALING,vScale);

}

load: what,io
{
    if(what == SCENEMODE)   // processing an ASCII scene file
    {
        sHeader = io.read().asStr();

        if(sHeader == sTitle + " " + sVersion)
            {
            GroundItemName = io.read().asStr();
            bWorldCoordinates = io.read().asInt();
            nRadius = io.read().asNum();
            nStretchX = io.read().asNum();
            nStretchZ = io.read().asNum();
            }
    }
}

save: what,io
{
    if(what == SCENEMODE)
    {
        // Header
        io.writeln(sTitle + " " + sVersion);

        if(GroundItem != nil)
            {
            io.writeln(string(GroundItem.name));
            }
        else
            {
            io.writeln("nil");
            }    

        io.writeln(bWorldCoordinates);
        io.writeln(nRadius);
        io.writeln(nStretchX);
        io.writeln(nStretchZ);
    }
}

options
{
    if(reqisopen())
        {
        reqend();
        return;
        }
 
    reqbegin(sTitle + " " + sVersion);

    ctrl_c0 = ctlcheckbox("World Coordinates",bWorldCoordinates);
    ctrl_c1 = ctlmeshitems("Ground Item",GroundItem);
    ctrl_c2 = ctldistance("Radius",nRadius);
    ctrl_c3 = ctlpercent("Stretch X",nStretchX);
    ctrl_c4 = ctlpercent("Stretch Z",nStretchZ);

    // Developer
    ctlsep();
    ctrl_dev0 = ctltext("","developer: Stephen Culley","http://www.stephenculley.co.uk");

    // Refresh
    ctlrefresh(ctrl_c0,"refresh_c0"); // World Coordinates
    ctlrefresh(ctrl_c1,"refresh_c1"); // Ground Item
    ctlrefresh(ctrl_c2,"refresh_c2"); // Radius
    ctlrefresh(ctrl_c3,"refresh_c3"); // Stretch X
    ctlrefresh(ctrl_c4,"refresh_c4"); // Stretch Z

    reqopen();
}

refresh_c0:value // World Coordinates
{
    bWorldCoordinates = value;
}

refresh_c1:value // Ground Item
{
    GroundItem = value;
}

refresh_c2:value // Radius
{
    nRadius = value;
}

refresh_c3:value // Stretch X
{
    nStretchX = value;
}

refresh_c4:value // Stretch Z
{
    nStretchZ = value;
}
All scripts available at my Google Drive at
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs

No comments:

Post a comment