//-------------------------------- //Parent_to_Null 0.1 //by Jeremy Hardin @warnings @name "Parent_to_Null" @script generic generic { //here I declare the current scene as a scene object agent so I can get some info about it. //specifically parent in place. I want this option specifically because I //will be assigning parenting in this script and will need parent in place off. scene = Scene(); par_in_place = scene.generalopts[3]; //now i'll be making use of the temp directory for object's motions. first, //i'll need to find the directory. then I'll assign it to a variable. we'll //also get the content director into a variable for future reference. //using the temp_dir variable, i'll change our current working directory to the //the temp directory. I'll then make a directory called "parent_to_null" //for all the motion files. Afterward's we'll change that to the current working //directory. temp_dir = getdir("Temp"); content_dir = getdir("Content"); chdir(temp_dir); mkdir("parent_to_null"); chdir("parent_to_null"); //to remove motion from the objects before parenting them to nulls, we are //loading a motion file with no motion in it. this is stored in binary data //below. using the "write binary" mode of the File Object Agent, we'll output //the motion file into our current working directory, taking care to close the //File Object Agent afterwards. output = File("nomotion.mot","wb"); output.writeData(nomotion); output.close(); //if parent in place was on initially we need it off for the time being if(par_in_place == 1) { ParentInPlace(); } //Alright, we need to make an array of the selected objects. We're //doing this so that our script can allow for multiple selections. //after declaring the array, we assign the size of the array to a variable. //We do this so that we can select each member of the array individually //by number (up to the size of the array) and not lose the original selection. s = scene.getSelect(); arraysize = size(s); //using a for statement, we select each selected object one by one and perform //our desired operations. for(x = 1; x <= arraysize; x++) { //we assign the currently selected object's name to a variable itemname = s[x].name; //now we need to assign the selected object to an object agent. //the problem is that we want our script to work with objects, //lights, or cameras. so we'll use the .genus method to detect //which type it is. then we'll assign it to the appropriate //object agent. if(s[x].genus == 1) { selected = Mesh(itemname); } if(s[x].genus == 2) { selected = Light(itemname); } if(s[x].genus == 3) { selected = Camera(itemname); } if(s[x].genus == 4) { error("Bones must remain parented to the object they belong to."); } //now that the current object is assigned to an Object Agent, //we can select it by it's id. Then we'll construct the command //to save it's motion. After we employ the newly constructed //command, we'll detect if it's parented or targeted to anything. //we do this so that the object will move exactly as it did before, //regardless of it's place in the heirarchy. And last in this section //we'll add the null that will become the current object's parent. //we don't give the null it's final name yet in case that name already //exists in the scene. this could cause potential conflicts. So we'll //call it "parent_to_null_parentnull". It's unlikely that this will already //exist in the user's scene. SelectItem(selected.id); savestringadd = ("SaveMotion " + itemname + x + ".mot"); CommandInput(savestringadd); item_parent = selected.parent; item_target = selected.target; AddNull("parent_to_null_parentnull"); //since we added the null, it is selected. We need to reselect our current //object. Then we'll load the static motion file that we created above. //Following this we parent the current object to the "parent_to_null_parentnull". //We then select the "parent_to_null_parentnull" object again and construct the //Load motion command in the same way we saved it above and execute the command. SelectItem(selected.id); LoadMotion("nomotion.mot"); ParentItem("parent_to_null_parentnull"); SelectItem("parent_to_null_parentnull"); loadstringadd = ("LoadMotion " + itemname + x + ".mot"); CommandInput(loadstringadd); //if the original item was parented and or targeted, we parent and or target //the new null. Finally, we rename the "parent_to_null_parentnull" to have //the same name as the current object with "_ParentNull" appended to the end //of it. if(item_parent != nil) { ParentItem(item_parent.name); } if(item_target != nil) { TargetItem(item_target.name); } namestringadd = ("Rename " + itemname + "_ParentNull"); CommandInput(namestringadd); //our for statement ends here } //if parent in place was on initially, we know we turned it off above. //we need to turn it back on. Also, you should ALWAYS change the user's //current working directory BACK to the content directory when you finish. //otherwise the next time they load a scene they'll get all kinds of errors. if(par_in_place == 1) { ParentInPlace(); } chdir(content_dir); //end of the generic script } //below is our motion file with no motion in it. it has been converted to //binary data and is being stored here until called upon above as "nomotion". @data nomotion 700 076 087 077 079 013 051 013 013 078 117 109 067 104 097 110 110 101 108 115 032 057 013 067 104 097 110 110 101 108 032 048 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 067 104 097 110 110 101 108 032 049 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 067 104 097 110 110 101 108 032 050 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 067 104 097 110 110 101 108 032 051 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 067 104 097 110 110 101 108 032 052 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 067 104 097 110 110 101 108 032 053 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 067 104 097 110 110 101 108 032 054 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 049 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 067 104 097 110 110 101 108 032 055 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 049 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 067 104 097 110 110 101 108 032 056 013 123 032 069 110 118 101 108 111 112 101 013 032 032 049 013 032 032 075 101 121 032 049 032 048 032 048 032 048 032 048 032 048 032 048 032 048 032 048 013 032 032 066 101 104 097 118 105 111 114 115 032 049 032 049 013 125 013 @end