So, for fun, I knocked up a little tool that would let her experiment quickly and easily. Z&A Flex Linkset was born:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////// | |
// Z&A Flex Linkset | |
// By Antony Fairport | |
// | |
// Z&A Flex Linkset - Apply flexible path params to a whole linkset. | |
// | |
// Revision history: | |
// ------------------------------------------------------------ | |
// | |
// 2017-11-05 | |
// Initial revision. | |
////////////////////////////////////////////////////////////////////// | |
// Globals. | |
integer g_iSoftness = 2; | |
float g_nGravity = 0.300; | |
float g_nFriction = 2.000; | |
float g_nWind = 0.000; | |
float g_nTension = 1.000; | |
vector g_vForce; | |
////////////////////////////////////////////////////////////////////// | |
// Refresh the flexible path for the whole linkset. | |
RefreshFlexi() | |
{ | |
llSetLinkPrimitiveParamsFast( LINK_SET, [ | |
PRIM_FLEXIBLE, TRUE, g_iSoftness, g_nGravity, g_nFriction, g_nWind, g_nTension, g_vForce | |
] ); | |
} | |
////////////////////////////////////////////////////////////////////// | |
// Get a parameter, with error checking and reporting. | |
float GetParam( list lCmd, string sName, float nCurrent, float nMin, float nMax ) | |
{ | |
float n = (float) llList2String( lCmd, 2 ); | |
if ( ( n >= nMin ) && ( n <= nMax ) ) | |
{ | |
nCurrent = n; | |
} | |
else | |
{ | |
llSay( 0, "Invalid value. " + sName + " should be in the range " + | |
( (string) nMin ) + " to " + ( (string) nMax ) + " inclusive." ); | |
} | |
return nCurrent; | |
} | |
////////////////////////////////////////////////////////////////////// | |
// Default state. | |
default | |
{ | |
////////////////////////////////////////////////////////////////// | |
// State entry. | |
state_entry() | |
{ | |
// Set the initial state. | |
RefreshFlexi(); | |
// Start listening to the owner. | |
llListen( 0, "", llGetOwner(), "" ); | |
} | |
////////////////////////////////////////////////////////////////// | |
// Handle a listen. | |
listen( integer channel, string name, key id, string message ) | |
{ | |
if ( ( channel == 0 ) && ( id == llGetOwner() ) ) | |
{ | |
// Break up what was said. | |
list lCmd = llParseString2List( message, [ " " ], [] ); | |
string sPrefix = llList2String( lCmd, 0 ); | |
// Is it a flex command? | |
if ( sPrefix == "flex" ) | |
{ | |
// It is. Pull out the next part. | |
string sCmd = llList2String( lCmd, 1 ); | |
if ( sCmd == "soft" ) | |
{ | |
integer i = (integer) llList2String( lCmd, 2 ); | |
// Does it look like a valid softness value? | |
if ( ( i >= 0 ) && ( i <= 3 ) ) | |
{ | |
g_iSoftness = i; | |
} | |
else | |
{ | |
llSay( 0, "Invalid value. Softness should be in the range 0 to 3 inclusive." ); | |
} | |
} | |
else if ( sCmd == "grav" ) | |
{ | |
g_nGravity = GetParam( lCmd, "Gravity", g_nGravity, -10.0, 10.0 ); | |
} | |
else if ( sCmd == "drag" ) | |
{ | |
g_nFriction = GetParam( lCmd, "Drag", g_nFriction, 0.0, 10.0 ); | |
} | |
else if ( sCmd == "wind" ) | |
{ | |
g_nWind = GetParam( lCmd, "Wind", g_nWind, 0.0, 10.0 ); | |
} | |
else if ( sCmd == "ten" ) | |
{ | |
g_nTension = GetParam( lCmd, "Tension", g_nTension, 0.0, 10.0 ); | |
} | |
else if ( sCmd == "fx" ) | |
{ | |
g_vForce.x = GetParam( lCmd, "Force (X)", g_vForce.x, -10.0, 10.0 ); | |
} | |
else if ( sCmd == "fy" ) | |
{ | |
g_vForce.y = GetParam( lCmd, "Force (Y)", g_vForce.y, -10.0, 10.0 ); | |
} | |
else if ( sCmd == "fz" ) | |
{ | |
g_vForce.z = GetParam( lCmd, "Force (Z)", g_vForce.z, -10.0, 10.0 ); | |
} | |
else if ( sCmd == "show" ) | |
{ | |
llSay( 0, "Current flexible path parameters:\n" + | |
"Softness: " + ( (string) g_iSoftness ) + "\n" + | |
"Gravity.: " + ( (string) g_nGravity ) + "\n" + | |
"Drag....: " + ( (string) g_nFriction ) + "\n" + | |
"Wind....: " + ( (string) g_nWind ) + "\n" + | |
"Force X.: " + ( (string) g_vForce.x ) + "\n" + | |
"Force Y.: " + ( (string) g_vForce.y ) + "\n" + | |
"Force Z.: " + ( (string) g_vForce.z ) + "\n" ); | |
} | |
else if ( sCmd == "reset" ) | |
{ | |
llResetScript(); | |
} | |
else if ( sCmd == "done" ) | |
{ | |
llSay( 0, "Sorry you don't want me any more. Enjoy your flexibility. :-(" ); | |
llRemoveInventory( llGetScriptName() ); | |
} | |
else if ( sCmd == "help" ) | |
{ | |
llSay( 0, "flex < soft | grav | drag | wind | ten | fx | fy | fz > <value>" ); | |
llSay( 0, "flex show" ); | |
llSay( 0, "flex reset" ); | |
llSay( 0, "flex done" ); | |
} | |
// Finally, refresh. | |
RefreshFlexi(); | |
} | |
} | |
} | |
} |
flex soft <value>
flex grav <value>
flex drag <value>
flex wind <value>
flex ten <value>
flex fx <value>
flex fy <value>
flex fz <value>
As well as commands for setting the flexible path parameters, there are also commands for controlling the script itself. To see the current parameters:
flex show
To reset the parameters to their default:
flex reset
And when you're done with the script and you want it to remove itself from the object:
flex done
And that's it. It was fun to knock together, Mistress had fun playing around with it, hopefully it's of some use to someone else too.
No comments:
Post a Comment