// ===================================================================== // Spin It // skimi3d script library ยท https://grid.skimi3d.com/scripts/spin-it // // Makes a prim turn, endlessly, for free. // // This is the cheapest moving thing you can put in a region, and it is // worth understanding why. llTargetOmega does not turn the object at // all. It tells every viewer nearby "draw this one spinning", and the // viewers do the work on their own machines. The region sends one // message and then goes back to sleep. A hundred of these cost a // region less than one script nudging a prim round with llSetRot. // // The price of that bargain is written at the bottom of this file and // in "What it will not do" on the library page. Read it before you use // this for anything that has to actually move something. // ===================================================================== // --------------------------------------------------------------------- // Settings // --------------------------------------------------------------------- // The axis it turns around, in the prim's own body. // <0.0, 0.0, 1.0> upright, like a carousel or a radar dish // <0.0, 1.0, 0.0> on its side, like a wheel or a windmill // <1.0, 0.0, 0.0> the other way on its side vector AXIS = <0.0, 0.0, 1.0>; // Turns per minute. 6.0 is one slow turn every ten seconds, which suits // a windmill; 60.0 is one turn a second, which suits a fan. A negative // number turns it the other way. float RPM = 6.0; // Should it be turning as soon as it is rezzed? integer START_SPINNING = TRUE; // Touch to stop it, touch again to start it. Set to FALSE for something // that should just turn and be left alone, like a planet or a sign. integer TOUCH_TO_TOGGLE = TRUE; // Who may touch it. 0 = everyone, 1 = only the owner, 2 = only people // wearing the same group tag. integer WHO_MAY_TOUCH = 0; // --------------------------------------------------------------------- // Everything below here is the machinery // --------------------------------------------------------------------- integer gSpinning = FALSE; spin(integer on) { if (on) { // llTargetOmega counts in radians a second, which nobody thinks // in. Turns per minute is the number you can picture, so the // setting is in those and the conversion lives here, once. float rate = RPM * TWO_PI / 60.0; llTargetOmega(llVecNorm(AXIS), rate, 1.0); } else { // A zero axis is how you stop it. Setting the rate to zero on // its own leaves some viewers still drawing the last spin. llTargetOmega(ZERO_VECTOR, 0.0, 0.0); } gSpinning = on; } integer mayTouch(key who) { if (WHO_MAY_TOUCH == 1) return who == llGetOwner(); if (WHO_MAY_TOUCH == 2) return llSameGroup(who); return TRUE; } default { state_entry() { spin(START_SPINNING); } touch_start(integer total) { if (!TOUCH_TO_TOGGLE) return; key who = llDetectedKey(0); if (!mayTouch(who)) { llRegionSayTo(who, 0, "This one is not yours to stop."); return; } spin(!gSpinning); } on_rez(integer start) { // The spin is a property of the prim, not of the script, and a // rezzed copy can arrive already turning from whatever state it // was taken in. Say it again so rezzed and edited copies agree. spin(START_SPINNING); } changed(integer what) { // A copy inherits the old spin. Re-stating it after a change of // owner or inventory keeps a boxed and re-rezzed one honest. if (what & (CHANGED_OWNER | CHANGED_INVENTORY)) spin(gSpinning); } } // --------------------------------------------------------------------- // The catch, in full // // The object does not turn. The viewers draw it turning. // // That means llGetRot never changes, however long it has been going. // Nothing mounted on it turns with it. It will not push anything, will // not sweep anyone off a platform, and a sensor or a camera sitting on // it keeps looking the same way for ever. Two viewers standing side by // side may show it at different angles, because each one started // drawing at its own moment. // // For a windmill, a fan, a sign, a planet, a shop display, none of that // matters and you get the motion for nothing. For a turnstile, a // carousel with people on it, or a hand of a clock you want to read, // every word of it matters and you need a script that really moves the // prim. Move Along Points in this library is the one to start from. // ---------------------------------------------------------------------