--//////////////////////////////////////////////_FUNCTIONS_////////////////////////////////////////////////////// Struct BlobCreator ( --///VARIABLES/// MyObjectCount = selection, SetFromTime, SetToTime, MySnapshotedObjects=#(), MyBlobElements =#(), MyObject, LayerCount, MyImportedObjects=#(), DeleteOldState, ColourGuidesState, FullAnimON = false, UnfilteredList =#(), --///Functions/// --Look into the selected mesh' skin modifier and select all the bones fn RSTA_GetControllers = ( BoneNameArray = #() MyObjCount = #() MyObjCount = selection as array for TheObj = 1 to MyObjCount.count do ( MyObject = MyObjCount[TheObj] select MyObject MyBoneNb = skinOps.GetNumberBones MyObject.modifiers[#skin] For TheBone = 1 to MyBoneNb do ( MyBoneName = skinOps.GetBoneName MyObject.modifiers[#skin] TheBone 1 appendifunique BoneNameArray MyBoneName ) ) select MyObjCount return BoneNameArray ), fn RSTA_Snapshot_KeyFrames Density = ( --Loop from SetFromTime to SetToTime For BlobKey = SetFromTime to SetToTime by Density do ( --move in the timeline : sliderTime = ( BlobKey as time) --Snapshot... snapshot MyObject ) ), -- Place any new created meshs into an array fn RSTA_CreateBlobArray = ( MyObjectsCreated = callbacks.notificationParam() Append MySnapshotedObjects MyObjectsCreated Return MySnapshotedObjects ), -- Get int between 0 and 30 from % : (SpinValue*30)/100 fn RSTA_Get_Optimization = ( OptimizeAmount = (BlobCreator.spn_Fidel.value*30)/100 Return OptimizeAmount ), --Attach every Keyframes together fn RSTA_AttachBlobParts MySnapshotedObjects OptimizeAmount = ( -- Attach them all together --1sts undo Off to fasten things. converttopoly MySnapshotedObjects[1] undo off ( for Themesh = 2 to MySnapshotedObjects.count do ( --optimize snaphoted mesh meshop.optimize MySnapshotedObjects[Themesh] (OptimizeAmount as Float) 1.0 0.1 00 saveMatBoundries:False saveSmoothBoundries:False autoEdge:false --now attach polyop.attach MySnapshotedObjects[1] MySnapshotedObjects[Themesh] ) ) Append MyBlobElements MySnapshotedObjects[1] return MyBlobElements ), --Attach every Blob-elements togetehr fn RSTA_AttachBlobElements MyBlobElements = ( select MyBlobElements[1] for Themesh = 2 to MyBlobElements.count do ( toAtach = MyBlobElements[Themesh] selection[1].EditablePoly.attach toAtach MyBlobElements[1] ) return MyBlobElements[1] ), -- Get all controler in skin modifier list of selected objects, then detect the full animation lenght fn RSTA_Detect_Anim_Lenght BoneNameArray = ( -- Loop into the selection and find the range for each controllers local StartFrames = #() local EndFrames = #() For obj = 1 to BoneNameArray.count do ( ctrl = getnodebyname BoneNameArray[obj] GetAnimRange = (gettimerange ctrl.pos.controller[1].controller ) appendifUnique StartFrames (GetAnimRange.start.frame as integer) appendifUnique EndFrames (GetAnimRange.end.frame as integer) ) -- Now isolate the smallest value in StartFrames... --... and the bigger in EndFrames... Sort StartFrames Sort EndFrames LastOne = EndFrames.count --Feed Set From and To variable with it so the script work the exact same way SetFromTime = StartFrames[1] SetToTime = EndFrames[LastOne] ), --Import FBX animation fn RSTA_ImportFBX = ( --"The FBX Importer Plugin must be loaded in memory" pluginManager.loadClass FbxImporter actionMan.executeAction 0 "40195" -- File: Merge File ), --get a slot in the material editor, create a multi sub material, 3 ID, 3 colours, Green, Grey, Red fn RSTA_Create_ColourGuide = ( meditMaterials[24] = Multimaterial () meditMaterials[24].name = "ColourGuides" meditMaterials[24].numsubs = 3 meditMaterials[24].names = #("Start","Middle","End") --Green meditMaterials[24].materialList[1].Diffuse = color 0 247 12 --Grey meditMaterials[24].materialList[2].Diffuse = color 201 201 201 --Red meditMaterials[24].materialList[3].Diffuse = color 255 67 67 ), --Assign MatID on Blob Elements for ColourGuides material t. 1st item = 1st frame snapshoted = Green. Middles = grey, last = Red fn RSTA_Assign_ColourGuides MySnapshotedObjects = ( -- First the Greys For Elementi = 1 to MySnapshotedObjects.count do ( MyElement = MySnapshotedObjects[Elementi] FaceNb = getNumFaces MyElement For Face = 1 to FaceNb do ( setFaceMatID MyElement Face 2 ) ) --Now the Green MyGreenElement = MySnapshotedObjects[1] FaceNb = getNumFaces MyGreenElement For Face = 1 to FaceNb do ( setFaceMatID MyGreenElement Face 1 ) --Then the Red Last = MySnapshotedObjects.count MyRedElement = MySnapshotedObjects[Last] FaceNb = getNumFaces MyRedElement For Face = 1 to FaceNb do ( setFaceMatID MyRedElement Face 3 ) ), --Create a new layer and put the newly created Blob inside fn RSTA_LayerCreation MyBlobElements = ( try ( --create layer (add layer count number to create a new layer for each new blob) Layer01 = LayerManager.newLayerFromName ("MoveFreez" + (LayerCount as string) ) --add the Blob into this layer Layer01.addnode MyBlobElements[1] --increase LayerCount LayerCount = (LayerCount +1) ) catch() ) ) StructBlob = BlobCreator() --//////////////////////////////////////////////_UI_////////////////////////////////////////////////////// --try(destroydialog BlobCreator) catch() Rollout BlobCreator "Motion Freeze" ( --R* Banner dotNetControl rsBannerPanel "Panel" pos:[2,3] height:32 width:( BlobCreator.width - 5) local banner = makeRsBanner dn_Panel:rsBannerPanel versionNum:0.01 versionName:"" wiki:"WIKI_NAME" filename:(getThisScriptFilename()) group "FBX loader" ( Button btn_Load "Load" width:45 height:25 align:#right offset:[-78,-5] toolTip: "Load your animation as FBX" checkbox cbx_DeleteOld "Delete Old" align:#right offset:[2,-22] checked:true toolTip: "Remove previously loaded FBX before loading new one" ) Spinner spn_dens "Animation Steps" range:[1,10,1] fieldWidth:28 pos:[5,90] type: #integer toolTip: "Animation steps within the provided range. The bigger the number, the less snapshoted keys. " Spinner spn_Fidel "Mesh Optimise%" range:[1,100,50] fieldWidth:28 pos:[5,110] type: #integer toolTip: "0 = No Mesh optimization. The higer the more optimized" group "Freeze Animation :" ( Button btn_From "From" width:30 height:30 align:#right offset:[-100,-5] toolTip: "First snapshoted frame" edittext EdT_From "" width:60 height:17 align:#right offset:[-40,-28] Button btn_To "To" width:30 height:30 align:#right offset:[-100,4] toolTip: "Last snapshoted frame" edittext EdT_To "" width:60 height:17 align:#right offset:[-40,-26] checkbox cbx_FullAnimation "Full Animation" align:#right offset:[-40,4] toolTip: "Snapshot every frames of the animation (will clamp if animation start before the frame 0)" ) checkbox cbx_ColourGuides "Colour Guides" align:#right offset:[-20,-2] checked:true toolTip: "Add colours guides to the snapshots. First frame = Green, Last = Red, in between = Grey" Button btn_create "Create Blob" width:90 height:25 align:#right offset:[-20,-2] toolTip: "Launch the Blob Creation" Button btn_removeFBX "RemoveFBX" width:90 height:25 align:#right offset:[-20,-2] toolTip: "Remove the last imported FBX nodes from your scene" --//////////////////////////////////////////////_EVENTS_////////////////////////////////////////////////////// --delete last fbx loaded from your scene (if you can't, it's already been deleted so do nothing) on btn_removeFBX pressed do ( Try ( delete StructBlob.MyImportedObjects ) catch () ) on BlobCreator open do ( StructBlob.LayerCount = 1 banner.setup() StructBlob.DeleteOldState = True StructBlob.ColourGuidesState = True ) on cbx_ColourGuides changed Ischecked do ( if Ischecked == true do ( StructBlob.ColourGuidesState = True ) if Ischecked == false do ( StructBlob.ColourGuidesState = False ) ) on cbx_DeleteOld changed Ischecked do ( if Ischecked == true do ( StructBlob.DeleteOldState = True ) if Ischecked == false do ( StructBlob.DeleteOldState = False ) ) -- Erease the current animation if founded and load another one on btn_Load pressed do ( --if StructBlob..DeleteOldState == true try to delete any node contained in StructBlob.MyImportedObjects if StructBlob.DeleteOldState == True do ( Try ( select StructBlob.MyImportedObjects delete selection StructBlob.MyImportedObjects = #() )catch() ) --Bring FBX importer window StructBlob.RSTA_ImportFBX() -- The nodes imported by fbx will all be selected by default, use this selection to add all of them in an array StructBlob.MyImportedObjects = selection as array --unselect all clearSelection() ) --if checked disable From and True entries and Freeze the whole animation available on cbx_FullAnimation changed Ischecked do ( if Ischecked == true do ( btn_From.enabled = false EdT_From.enabled = false btn_To.enabled = false EdT_To.enabled = false StructBlob.FullAnimON = True ) if Ischecked == false do ( btn_From.enabled = true EdT_From.enabled = true btn_To.enabled = true EdT_To.enabled = true StructBlob.FullAnimON == False ) ) on btn_From pressed do ( StructBlob.SetFromTime = sliderTime.frame BlobCreator.EdT_From.text = (sliderTime.frame as string) ) on btn_To pressed do ( StructBlob.SetToTime = sliderTime.frame BlobCreator.EdT_To.text = (sliderTime.frame as string) ) on EdT_From entered EnteredFrom do ( StructBlob.SetFromTime = EnteredFrom sliderTime = (EnteredFrom as time) ) on EdT_To entered EnteredTo do ( StructBlob.SetToTime = EnteredTo sliderTime = (EnteredTO as time) ) on btn_create pressed do ( StructBlob.MyObjectCount = #() StructBlob.MyBlobElements =#() StructBlob.UnfilteredList = selection --First look in the selection and remove every node without skin modifier for TheNode = 1 to StructBlob.UnfilteredList.count do ( MyNode = StructBlob.UnfilteredList[TheNode] -- now iterate in the modifers of the object For theModifiers in MyNode.modifiers do ( If classof theModifiers == skin do ( append StructBlob.MyObjectCount MyNode ) ) ) select StructBlob.MyObjectCount --Get animation lenght if Full Animation is On if StructBlob.FullAnimON == True do ( --Get animation range -- 1st get all the bones selected BoneNameArray = StructBlob.RSTA_GetControllers() StructBlob.RSTA_Detect_Anim_Lenght BoneNameArray --Clamp animation to animation range animationRange if StructBlob.SetFromTime < animationRange.start do ( StructBlob.SetFromTime = (animationRange.start as integer) ) ) --if colour guides is trigger, create a multi sub material, 3 ID, 3 colours, Green (1st snapshoted frame), Grey (middles), Red(last one) if StructBlob.ColourGuidesState == True do ( StructBlob.RSTA_Create_ColourGuide () ) for TheObj = 1 to StructBlob.MyObjectCount.count do ( StructBlob.MySnapshotedObjects =#() StructBlob.MyObject = StructBlob.MyObjectCount[TheObj] -- Density = Animation Steps Density = BlobCreator.spn_dens.value --Start callback. It will detect any new created object and put them into an array callbacks.addScript #nodeCreated "StructBlob.RSTA_CreateBlobArray()" id:#DetectNewNods --Now Snapshot meshs everyframes depending of Density StructBlob.RSTA_Snapshot_KeyFrames Density --End CallBack callbacks.removeScripts #nodeCreated id:#DetectNewNods --Get your optimize amount OptimizeAmount = StructBlob.RSTA_Get_Optimization () --if colour guides is trigger assign Materials ID acordingly if StructBlob.ColourGuidesState == True do ( StructBlob.RSTA_Assign_ColourGuides StructBlob.MySnapshotedObjects ) --Now You can attach every newly created meshs StructBlob.MyBlobElements = StructBlob.RSTA_AttachBlobParts StructBlob.MySnapshotedObjects OptimizeAmount ) --if colour guides is trigger, apply previously created colour guides material to the Blob if StructBlob.ColourGuidesState == True do ( For TheMesh = 1 to StructBlob.MyBlobElements.count do ( MyBlob = StructBlob.MyBlobElements[TheMesh] MyBlob.material = meditMaterials[24] ) ) --Now attach all diferent Blob-Elements together. StructBlob.RSTA_AttachBlobElements StructBlob.MyBlobElements -- COLOR GUIDES ISSUE HERE -- Put the created Blob into a new layer. StructBlob.RSTA_LayerCreation StructBlob.MyBlobElements ) ) createdialog BlobCreator width:150 height:315