Files
2025-09-29 00:52:08 +02:00

458 lines
14 KiB
Plaintext
Executable File

--//////////////////////////////////////////////_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