integer CHANNEL = -1; //vector base_initial_pos; vector cur_base_pos; rotation base_initial_rot; rotation cur_base_rot; vector object_initial_pos=<-1,-1,-1>; rotation object_initial_rot; list parsecmd(string msg) { return llParseStringKeepNulls(msg,["|"],["|"]); } rotate_around_point() { vector center = cur_base_pos; llOwnerSay("base pos: "+(string)cur_base_pos+ " center "+(string)center); vector point = object_initial_pos; // divide current rotation by the initial_rotation // gives the actual rotation made rotation diffrot = cur_base_rot / base_initial_rot; llOwnerSay("cur_base_pos: "+(string)cur_base_pos+"object_initial_pos: "+(string)point+" rot:"+(string)cur_base_rot+" base_initial_rot:"+(string)base_initial_rot+" diffrot:"+(string)diffrot); // get actual rotation in radians vector eulero = llRot2Euler(diffrot); float theta = eulero.z; vector object_pos = llGetPos(); // according to https://academo.org/demos/rotation-about-point/ llOwnerSay("Rotating by "+(string)(theta)); // 1) first we need to get transform such that center is the center of coordinate float sin = llSin(theta); float cos = llCos(theta); // translate point back to origin: float px = point.x - center.x; float py = point.y - center.y; llOwnerSay("px: "+(string)px+" py: "+(string)py+" sin: "+(string)sin+" cos: "+(string)cos); // rotate point this is the core of rotation float xnew = px * cos - py * sin; float ynew = px * sin + py * cos; // translate point back: float nx = xnew + center.x; float ny = ynew + center.y; vector newpos = ; llOwnerSay("would change pos to "+(string)newpos); //llOwnerSay("rotated by "+(string)(theta*RAD_TO_DEG)+" degrees "); llSetLinkPrimitiveParamsFast( LINK_THIS, [ PRIM_POSITION, newpos, PRIM_ROTATION, object_initial_rot*diffrot]); } default { state_entry() { llListen(CHANNEL,"","",""); } listen(integer channel, string name, key id, string msg) { if(object_initial_pos==<-1,-1,-1>) { llOwnerSay("MUST reset the base before touching!"); return; } list result=parsecmd(msg); //llOwnerSay(llList2CSV(result)); string cmd = llList2String(result,0); cur_base_pos = (vector)llList2String(result,1); //llOwnerSay("cur_base_pos: "+(string)cur_base_pos); cur_base_rot = (rotation)llList2String(result,2); if(cmd=="RESET") { llOwnerSay("Reset"); base_initial_rot = cur_base_rot; //base_initial_pos = pos; object_initial_pos = llGetPos(); object_initial_rot = llGetRot(); } if(cmd=="ROTATED") { rotate_around_point(); } } }