Advertisement
itoibo

Prim Animator

Jan 25th, 2016
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.22 KB | None | 0 0
  1. // Open Prim Animator - by Todd Borst
  2. // Extensive Modifications by SignpostMarv Martin
  3.  
  4. // Note from Todd to other editors: Please document changes you have made to get proper credit.
  5. // Note from Todd to users: People may have edited the script from since I've posted it originally.
  6. // You can always view the original script by clicking the history tab.
  7.  
  8. // This is provided AS IS without support. Please don't bug me demanding
  9. // help or custom work for this free script.
  10.  
  11. // Summary: This is a simple prim animation script. Just add this script
  12. // to your object and a dialog will automatically pop up for you to use.
  13.  
  14. // Features:
  15. // -Single script "Prim Puppeteer" like animation tool
  16. // -Playback controllable through external scripts
  17. // -Animation is scalable and resizeable
  18. // -On-touch trigger built-in
  19. // -Completely free and open sourced
  20.  
  21. // License:
  22. // You are welcome to use this anyway you like, even bring to other grids
  23. // outside of Second Life. You are welcomed to sell it if you've made your
  24. // own improvements to it. This is effectively public domain. Have fun.
  25.  
  26. integer COMMAND_CHANNEL = 32;
  27.  
  28. integer primCount;
  29. integer commandListenerHandle = ERR_GENERIC;
  30.  
  31. list posList;
  32. list rotList;
  33. list scaleList;
  34. integer currentSnapshot;
  35. integer recordedSnapshots;
  36.  
  37. vector rootScale;
  38. vector scaleChange = <1.0, 1.0, 1.0>;
  39.  
  40. integer maxMemory;
  41. integer freeMemory;
  42.  
  43. // The values for playAnimationStyle means
  44. // 0 := no animation playing
  45. // 1 := play animation once
  46. // 2 := play animation looping
  47.  
  48. integer playAnimationStyle;
  49.  
  50. key op_import = "6b78fcc8-e147-4105-99a6-ff19b4bf559d";
  51. key op_export = "7c2ca168-2b64-4836-8727-8e62b78dbd44";
  52. key op_alter_rootScale = "f9d3389e-a78c-43f8-9e35-c11adec112a5";
  53.  
  54. // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  55. // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  56.  
  57. show_snapshot(integer snapNumber)
  58. {
  59. if (!snapNumber || recordedSnapshots < snapNumber)
  60. return;
  61.  
  62. vector rootPos = llGetPos();
  63. rotation rootRot = llGetRot();
  64.  
  65. vector pos;
  66. rotation rot;
  67. vector scale;
  68. list params;
  69.  
  70. integer i = 2;
  71. do
  72. {
  73. pos = llList2Vector(posList, ((snapNumber - 1)*(primCount - 1)) + (i - 2));
  74. rot = llList2Rot(rotList, ((snapNumber - 1)*(primCount - 1)) + (i - 2));
  75. scale = llList2Vector(scaleList, ((snapNumber - 1)*(primCount - 1)) + (i - 2));
  76.  
  77. if ( rootScale.x != 1.0 || rootScale.y != 1.0 || rootScale.z != 1.0 )
  78. {
  79. pos.x *= scaleChange.x;
  80. pos.y *= scaleChange.y;
  81. pos.z *= scaleChange.z;
  82. scale.x *= scaleChange.x;
  83. scale.y *= scaleChange.y;
  84. scale.z *= scaleChange.z;
  85. }
  86. params += [PRIM_LINK_TARGET, i,
  87. PRIM_POSITION, pos,
  88. PRIM_ROTATION, rot/rootRot,
  89. PRIM_SIZE, scale
  90. ];
  91.  
  92. if (64 < llGetListLength(params))
  93. {
  94. llSetLinkPrimitiveParamsFast(LINK_THIS, params);
  95. params = [];
  96. }
  97. }
  98. while (++i <= primCount);
  99.  
  100. if (llGetListLength(params))
  101. {
  102. llSetLinkPrimitiveParamsFast(LINK_THIS, params);
  103. params = [];
  104. }
  105. }
  106.  
  107. playAnimation(float delay, integer loop)
  108. {
  109. if (delay < 0.1)
  110. delay = 1.0;
  111.  
  112. if (loop == FALSE)
  113. playAnimationStyle = 1;
  114. else
  115. playAnimationStyle = 2;
  116.  
  117. if (1 <= recordedSnapshots)
  118. llSetTimerEvent(delay);
  119. }
  120.  
  121. showMenuDialog()
  122. {
  123. // return;
  124.  
  125. string temp = (string)((float)freeMemory/(float)maxMemory * 100.0);
  126. string menuText = "Free Memory: " + (string)freeMemory + " (" + llGetSubString(temp, 0, 4) +"%)"
  127. + "\nSnapshot " + (string)currentSnapshot +" of " + (string)recordedSnapshots
  128. + "\n\n[ Record ] - Record a snapshot of prim positions"
  129. + "\n[ Play ] - Play back all the recorded snapshots"
  130. + "\n[ Publish ] - Finish the recording process"
  131. + "\n[ Show Next ] - Show the next snapshot"
  132. + "\n[ Show Prev ] - Show the previous snapshot";
  133.  
  134. llDialog(llGetOwner(), menuText,
  135. ["Record","Play","Publish","Show Prev","Show Next","Loop","Stop","Export"], COMMAND_CHANNEL);
  136. }
  137. string truncate_float(float foo)
  138. {
  139. if (foo == 0.0)
  140. return "0";
  141. else if (foo == (float)((integer)foo))
  142. return (string)((integer)foo);
  143.  
  144. string bar = (string)foo;
  145.  
  146. while (llGetSubString(bar, -1, -1) == "0")
  147. bar = llGetSubString(bar, 0, -2);
  148.  
  149. if (llGetSubString(bar, -1, -1) == ".")
  150. bar = llGetSubString(bar, 0, -2);
  151.  
  152. return bar;
  153. }
  154.  
  155. calc_scaleChange()
  156. {
  157. if (rootScale != ZERO_VECTOR)
  158. {
  159. vector newScale = llGetScale();
  160.  
  161. if ( (newScale.x / rootScale.x) != scaleChange.x
  162. || (newScale.y / rootScale.y) != scaleChange.y
  163. || (newScale.z / rootScale.z) != scaleChange.z)
  164. {
  165. scaleChange.x = newScale.x / rootScale.x;
  166. scaleChange.y = newScale.y / rootScale.y;
  167. scaleChange.z = newScale.z / rootScale.z;
  168. }
  169. }
  170. }
  171.  
  172. default
  173. {
  174. state_entry()
  175. {
  176. maxMemory = llGetFreeMemory();
  177. freeMemory = llGetFreeMemory();
  178.  
  179. primCount = llGetNumberOfPrims();
  180. commandListenerHandle = llListen(COMMAND_CHANNEL,"", llGetOwner(), "");
  181. showMenuDialog();
  182.  
  183. rootScale = llGetScale();
  184. if (llGetInventoryType("OPA Notecard Import - 2011-11-03") == INVENTORY_SCRIPT){
  185. llResetOtherScript("OPA Notecard Import - 2011-11-03");
  186. }
  187. }
  188.  
  189. // Feel free to remove this on-touch trigger if you are using your own script to control playback
  190. /* touch_start(integer num_detected)
  191. {
  192. if (commandListenerHandle == ERR_GENERIC)
  193. {
  194. if (playAnimationStyle == 0)
  195. playAnimation(1.0,TRUE);
  196. else
  197. {
  198. playAnimationStyle = 0;
  199. llSetTimerEvent((float)FALSE);
  200. }
  201. }
  202. }
  203. */
  204. changed(integer change)
  205. {
  206. if (change & CHANGED_SCALE)
  207. calc_scaleChange();
  208.  
  209. if (change & CHANGED_LINK)
  210. {
  211. if ( primCount != llGetNumberOfPrims() )
  212. {
  213. llOwnerSay("Link change detected, reseting script.");
  214. llResetScript();
  215. }
  216. }
  217. }
  218.  
  219. //The message link function is to allow other scripts to control the snapshot playback
  220. //This command will display snapshot #2:
  221. // llMessageLinked(LINK_ROOT, 2, "XDshow", NULL_KEY); llSleep(1.0);
  222. //
  223. //This command will play through all the recorded snapshots in ascending order. The number "1.0" is the delay speed and can be changed.
  224. // llMessageLinked(LINK_ROOT, 0, "XDplay", "1.0");
  225. //
  226. //This command will loop through all the recorded snapshots in ascending order. The number "1.0" is the delay speed and can be changed.
  227. // llMessageLinked(LINK_ROOT, 0, "XDplayLoop", "1.0");
  228. //
  229. //To stop any playing animation use
  230. // llMessageLinked(LINK_ROOT, 0, "XDstop", NULL_KEY);
  231.  
  232. link_message(integer sender_num, integer num, string str, key id)
  233. {
  234. if ("XDshow" == str && 1 <= num && num <= recordedSnapshots)
  235. show_snapshot(num);
  236. else if ("XDplay" == str)
  237. {
  238. currentSnapshot = 1;
  239. float delay = (float)((string)id);
  240. playAnimation(delay, FALSE);
  241. }
  242. else if ("XDplayLoop" == str)
  243. {
  244. float delay = (float)((string)id);
  245. playAnimation(delay, TRUE);
  246. }
  247. else if ("XDstop" == str)
  248. {
  249. playAnimationStyle = 0;
  250. llSetTimerEvent((float)FALSE);
  251. }
  252. else if ("XDexport" == str && !num)
  253. {
  254. list export = [];
  255. string foo;
  256. vector bar;
  257. rotation baa;
  258. string baz;
  259.  
  260. integer i = 2;
  261. integer j = primCount;
  262.  
  263. do
  264. export += [llGetLinkName(i)];
  265. while (++i <= j);
  266.  
  267. llMessageLinked(sender_num, 1, llDumpList2String(export,"|") , op_export);
  268. export = [];
  269.  
  270. i = 0;
  271. j = llGetListLength(posList);
  272.  
  273. do
  274. {
  275. bar = llList2Vector(posList,i);
  276. export += ["<" + truncate_float(bar.x) + ","
  277. + truncate_float(bar.y) + "," + truncate_float(bar.z) + ">"];
  278. }
  279. while (++i < j);
  280.  
  281. llMessageLinked(sender_num, 2, llDumpList2String(export,"|") , op_export);
  282. export = [];
  283.  
  284. i = 0;
  285. j = llGetListLength(rotList);
  286.  
  287. do
  288. {
  289. baa = llList2Rot(rotList,i);
  290. export += ["<" + truncate_float(baa.x) + "," + truncate_float(baa.y)
  291. + "," + truncate_float(baa.z) + "," + truncate_float(baa.s) + ">"];
  292. }
  293. while (++i < j);
  294.  
  295. llMessageLinked(sender_num, 3, llDumpList2String(export,"|") , op_export);
  296. export = [];
  297.  
  298. i = 0;
  299. j = llGetListLength(scaleList);
  300.  
  301. do
  302. {
  303. bar = llList2Vector(scaleList,i);
  304. export += ["<" + truncate_float(bar.x) + ","
  305. + truncate_float(bar.y) + "," + truncate_float(bar.z) + ">"];
  306. }
  307. while (++i < j);
  308.  
  309. llMessageLinked(sender_num, 4, llDumpList2String(export,"|") , op_export);
  310. }
  311. else if ("XDmenu" == str)
  312. {
  313. showMenuDialog();
  314. }
  315. else if ("XDimportLength" == str && 0 < num)
  316. {
  317. list foo;
  318. list bar;
  319.  
  320. integer i;
  321. do
  322. {
  323. foo += [ZERO_VECTOR];
  324. bar += [ZERO_ROTATION];
  325. }
  326. while (++i < num);
  327.  
  328. posList = foo;
  329. scaleList = foo;
  330. rotList = bar;
  331. llMessageLinked(sender_num,-1,str,op_import);
  332. recordedSnapshots = num / (llGetNumberOfPrims() - 1);
  333. llMessageLinked(LINK_SET, recordedSnapshots, "XDrecordedSnapshots", NULL_KEY);
  334. currentSnapshot = 1;
  335. }
  336. else if ("XDrecordedSnapshots" == str && num == -1)
  337. {
  338. llMessageLinked(sender_num,recordedSnapshots,str,NULL_KEY);
  339. }
  340. else if (id == op_import && 0 <= num)
  341. {
  342. list params = llParseString2List(str, ["|"], []);
  343. vector impPos = (vector)llList2String(params, 0);
  344. rotation impRot = (rotation)llList2String(params, 1);
  345. vector impSize = (vector)llList2String(params, 2);
  346.  
  347. posList = llListReplaceList(posList, [impPos], num, num);
  348. rotList = llListReplaceList(rotList, [impRot], num, num);
  349. scaleList = llListReplaceList(scaleList, [impSize], num, num);
  350. }
  351. else if (id == op_alter_rootScale)
  352. {
  353. rootScale = (vector)str;
  354. calc_scaleChange();
  355. }
  356. }
  357.  
  358. listen(integer channel, string name, key id, string message)
  359. {
  360. list parsedMessage = llParseString2List(message, [" "], []);
  361. string firstWord = llToLower(llList2String(parsedMessage, 0));
  362. string secondWord = llToLower(llList2String(parsedMessage, 1));
  363.  
  364. if ("show" == firstWord && recordedSnapshots > 0)
  365. {
  366. llSetTimerEvent((float)FALSE);
  367.  
  368. if (secondWord == "next")
  369. {
  370. ++currentSnapshot;
  371.  
  372. if (recordedSnapshots < currentSnapshot)
  373. currentSnapshot = 1;
  374.  
  375. show_snapshot(currentSnapshot);
  376. }
  377. else if (secondWord == "prev")
  378. {
  379. --currentSnapshot;
  380.  
  381. if (currentSnapshot < 1)
  382. currentSnapshot = recordedSnapshots;
  383.  
  384. show_snapshot(currentSnapshot);
  385. }
  386. else
  387. {
  388. currentSnapshot = (integer)secondWord;
  389.  
  390. if (currentSnapshot && currentSnapshot <= recordedSnapshots)
  391. {
  392. show_snapshot(currentSnapshot);
  393. llOwnerSay("Showing snapshot: " + (string)currentSnapshot);
  394. }
  395. else
  396. {
  397. llOwnerSay("Invalid snapshot number given: " + (string) currentSnapshot +
  398. "\nA valid snapshot number is between 1 and " + (string) recordedSnapshots);
  399.  
  400. currentSnapshot = 1;
  401. }
  402. }
  403. }
  404. else if (firstWord == "record")
  405. {
  406. vector rootPos = llGetPos();
  407.  
  408. integer i = 2;
  409. do
  410. {
  411. vector pos = llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_POSITION]), 0);
  412.  
  413. pos.x -= rootPos.x;
  414. pos.z -= rootPos.z;
  415. pos.y -= rootPos.y;
  416. pos = pos / llGetRot();
  417. posList += pos;
  418.  
  419. rotation rot = llList2Rot(llGetLinkPrimitiveParams(i, [PRIM_ROTATION]), 0);
  420.  
  421. rot = rot / llGetRot();
  422. rotList += rot;
  423.  
  424. scaleList += llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_SIZE]), 0);
  425. }
  426. while (++i <= primCount);
  427.  
  428. ++recordedSnapshots;
  429.  
  430. llOwnerSay("Total number of snapshots recorded: " + (string)recordedSnapshots);
  431. freeMemory = llGetFreeMemory();
  432. }
  433. else if (firstWord == "play")
  434. {
  435. float delay = (float)secondWord;
  436. currentSnapshot = 1;
  437. playAnimation(delay, FALSE);
  438. }
  439. else if ("publish" == firstWord)
  440. {
  441. llSetTimerEvent((float)FALSE);
  442. playAnimationStyle = 0;
  443. currentSnapshot = 1;
  444.  
  445. llListenRemove(commandListenerHandle);
  446. commandListenerHandle = -1;
  447.  
  448. llOwnerSay("Recording disabled. Publish complete.\nClick me to toggle animation on/off.");
  449. }
  450. else if ("loop" == firstWord)
  451. {
  452. llMessageLinked(LINK_THIS, 0, "XDplayLoop", NULL_KEY);
  453. }
  454. else if ("stop" == firstWord)
  455. {
  456. llMessageLinked(LINK_THIS, 0, "XDstop", NULL_KEY);
  457. }
  458. else if ("export" == firstWord)
  459. {
  460. llOwnerSay("Should be exporting");
  461. llMessageLinked(LINK_THIS, 0, "XDexport", NULL_KEY);
  462. }
  463.  
  464. if (commandListenerHandle != ERR_GENERIC)
  465. showMenuDialog();
  466. }
  467.  
  468. timer()
  469. {
  470. show_snapshot(currentSnapshot);
  471.  
  472. if (currentSnapshot < recordedSnapshots)
  473. ++currentSnapshot;
  474. else
  475. {
  476. if (playAnimationStyle == 2)
  477. currentSnapshot = 1;
  478. else
  479. {
  480. llSetTimerEvent((float)FALSE);
  481.  
  482. if (commandListenerHandle != ERR_GENERIC)
  483. showMenuDialog();
  484. }
  485. }
  486. }
  487. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement