User:Lum Pfohl/LSL Goodies/Snippet/Align Prim Between Two Points

From Second Life Wiki
< User:Lum Pfohl‎ | LSL Goodies
Revision as of 05:55, 21 September 2009 by Lum Pfohl (Talk | contribs)

Jump to: navigation, search

Align Prim Between Two Points

Occasionally, I have a need to rez a prim such as a cylinder, between two points, lined up in that direction. The math for it is ridiculously easy, but maddeningly difficult to get right. So I've documented it below (the text coloring is not standard LSL - rather it is the coloring applied by my UltraEdit text editor. For a link to a sample 'wordfile' file UltraEdit, follow this link.

rez (vector v1, vector v2) {
  // Determine the midpoint between the two vectors to rez the prim
  vector rezPos = (v1 + v2) / 2.0 + llGetPos();
  // Setup for determining the rotation at which the prim will be rezzed
  // First, apply any constant transformations to the prim. In the example
  // below, the rezzed prim is a cylinder (shaped into a 'stick'). Tilt
  // the 'stick' which is aligned vertically by default - sideways by
  // 90 degrees (or PI/2)

  rotation rezRot = llEuler2Rot(<0.0, PI_BY_TWO, 0.0>)
  // Get a Unit Vector that points along the space v1 -> v2
  vector difference = llVecNorm(v2 - v1);
  // Now calculate the new prim rotation by the 'angle' made between
  // an Unit Vector in the X-axis, and the one calculated above. This value
  // will be multiplied (we multiply rotations values to rotate the previous
  // value). This aligns the prim lengthwise between the two points, v1 v2

  rezRot *= llRotBetween(<1.0, 0.0, 0.0>, difference);
  // Optionally, we will calculate the distance between the two points and
  // send it to the rezzed object as a value. Unfortunately, we can only
  // send integer values, but by multiplying the float value by 1000, we
  // can capture sufficient significant digits to be passed as an integer
  // The rezzed prim will have an 'on_rez(integer param)' event, which
  // can take the incoming param value and cast it to a float then divide
  // by 1000.0 to get the length.

  integer resLength = (integer)(llVecMag(v2 - v1) * 1000.0);
  // All this setup - now we finally rez the prim. The ZERO_VECTOR value
  // is provided as the rezzed speed. We don't want our prim to fly away.
  // The rezzed object is called 'pentaedge' in my example.

  llRezObject("pentaedge", rezPos, ZERO_VECTOR, rezRot, resLength);

Lum Pfohl 13:53, 21 September 2009 (UTC)

Lum's Quick Links
Click to Enlarge

Related topics