first, please, I'm begging, use php tags... quoting to get code is annoying and if it's a bad day I'll just skip it. (i'm probably not the only one).
ok a few things to simplify. your inverse rotation function can be acheived in one operation, allowing you to dump the function. to invert a rotation use
rotation.s *= -1; //-- equavalent to rot.s = rot.s * -1 or rot.s = -rot.s
next simplification, is your fractional change in magnitude of your rotation...
rot.s *= 2;
will halve the rotation degrees, and basicly acts as a denominator to your degrees movement. so the get 1/12 you'd multiply the s component by 12. to increase degree you'd multiply by a fraction, such as .5 to double.
I'm not even going to dive into the logic of your SetLocal/getParent rot functions, in fact I'm having trouble wrapping my head around what you were trying to do, but what I'm guessing is that you are swinging the object around it's axis based on it's starting global axis, rather than a local one, which is where the problem is cropping up.
assuming that I've got that right, and you're just trying to swing in a particular local direction, what you'd want is to add the incremental rotation to the current rotation, like this:
llSetLocalRot( rot2move * llGetRot() ); //-- amount to move goes first
now if I've got the intention of this all wrong, please ignore the next part, it's basically a tire swing I made that swings based on it's local facing, around it's root (or the center of a cut root prim rope in this case) very similarly to a door script
float gFltDegSwing = 10; //-- from 'center' position
integer gIntSteps = 12; //--should at least be 1
rotation gRotSwing;
rotation gRotSwingStep;
rotation gRotCurrent;
integer gIntCounter;
default{
state_entry(){
gRotSwing = llEuler2Rot( <gFltDegSwing, 0.0, 0.0> * DEG_TO_RAD );
gRotSwingStep = llEuler2Rot( <gFltSwing * 2.0 / (float)gIntSteps, 0.0, 0.0> * DEG_TO_RAD );
//-- times 2 because gRotSwing is .5 of total swing
}
touch_start( integer vIntTouched ){
state sMoving;
}
}
state sMoving{
state_entry(){
gRotCurrent = llGetRot();
//-- start the timer early to chain the calls together tighter
llSetTimerEvent( .2 );
//-- pre swing covers half the distance
llSetRot( gRotSwing * gRotCurrent );
}
timer(){
//-- kill the timer while we're looping to avoid extra queues/processing
llSetTimerEvent( 0.0 );
gIntCounter = 1;
//-- our loop will take use from gFltdegrees back, to gFltDegrees front,
//-- for a total of vFltDegrees * 2
do{
llSetRot( gRotCurrent = gRotSwingStep * gRotCurrent );
//-- should be faster than llSetRot( gRotSwingStep * llGetRot() ); but I haven't tested
}while (gIntSteps < ++gIntCounter){
//-- restart the timer a lil early
llSetTimerEvent( .2 );
//-- reverse or rotations
gRotSwingStep.s *= -1;
gRotSwing.s *= -1;
}
touch_start( integer vIntTouched ){
state default;
}
state_exit(){
//-- kill the timer so it doesn't run uselessly
llSetTimerEvent( 0.0 );
//-- apply half the swing to recenter
llSetRot( gRotSwing * gRotCurrent );
}
}