450 lines
13 KiB
Plaintext
Executable File
450 lines
13 KiB
Plaintext
Executable File
|
|
global gLatestIplGroupDummy = undefined
|
|
|
|
(
|
|
callbacks.removeScripts id:#RsStatedAnimTool
|
|
try gRsStatedAnimTool.Deinit() catch()
|
|
try (DestroyDialog RsAnimFinder) catch ()
|
|
try (CloseRolloutFloater RsStatedAnimFloater) catch ()
|
|
)
|
|
|
|
global gRsStatedAnimTool = sRsStatedAnimTool()
|
|
|
|
filein "pipeline/helpers/rigging/weldSkinnedMeshes.ms"
|
|
filein "pipeline/helpers/rigging/collapseChildMeshesAndSkin.ms"
|
|
filein "pipeline/helpers/rigging/rootReplace.ms"
|
|
filein "pipeline/helpers/animation/splitAnimHierarchy.ms"
|
|
|
|
rollout RsAnimFinder "Scene Animation Finder" width:170 height:166
|
|
(
|
|
listBox animGroupList "AnimGroups in scene:" height:8 align:#center
|
|
button loadButton "Load" width:70 height:20 align:#left across:2 visible:false
|
|
button cancelButton "Cancel" width:70 height:20 align:#right visible:false
|
|
progressbar findprogress "" pos:loadButton.pos height:20 visible:true
|
|
|
|
on RsAnimFinder open do
|
|
(
|
|
animGroupList.items = gRsStatedAnimTool.findAnimGroups theProgressbar:findprogress
|
|
|
|
findprogress.visible = false
|
|
#(loadButton, cancelButton).visible = true
|
|
)
|
|
on loadButton pressed do
|
|
(
|
|
if undefined!=animGroupList.selected then
|
|
gRsStatedAnimTool.loadAnim animGroupList.selected
|
|
::RsStatedAnimRollout.updateList()
|
|
DestroyDialog RsAnimFinder
|
|
)
|
|
on animGroupList doubleClicked arg do
|
|
(
|
|
if undefined!=animGroupList.selected then
|
|
gRsStatedAnimTool.loadAnim animGroupList.selected
|
|
::RsStatedAnimRollout.updateList()
|
|
DestroyDialog RsAnimFinder
|
|
)
|
|
on cancelButton pressed do
|
|
(
|
|
DestroyDialog RsAnimFinder
|
|
)
|
|
|
|
-- Creates this rollout with the right settings:
|
|
fn create =
|
|
(
|
|
try (DestroyDialog RsAnimFinder) catch ()
|
|
CreateDialog RsAnimFinder style:#(#style_border, #style_titleBar, #style_sysmenu) modal:true
|
|
)
|
|
)
|
|
|
|
rollout RsIPLGroupCreation "IPLGroup Dummy"
|
|
(
|
|
label lbl1 "Enter the unqiue IPL Group name:"
|
|
edittext iplGroupName ""
|
|
button submit "Create"
|
|
|
|
on RsIPLGroupCreation open do
|
|
(
|
|
gLatestIplGroupDummy = undefined
|
|
)
|
|
on submit pressed do
|
|
(
|
|
gLatestIplGroupDummy = statedAnimIPLDummy()
|
|
if undefined!=selection[1] then
|
|
gLatestIplGroupDummy.pos = selection[1].pos
|
|
gLatestIplGroupDummy.imapName = iplGroupName.text
|
|
::RsStatedAnimRollout.updateList()
|
|
DestroyDialog RsIPLGroupCreation
|
|
)
|
|
on iplGroupName entered val do
|
|
(
|
|
gLatestIplGroupDummy = statedAnimIPLDummy()
|
|
if undefined!=selection[1] then
|
|
gLatestIplGroupDummy.pos = selection[1].pos
|
|
gLatestIplGroupDummy.imapName = val
|
|
::RsStatedAnimRollout.updateList()
|
|
DestroyDialog RsIPLGroupCreation
|
|
)
|
|
)
|
|
|
|
rollout RsStatedAnimRollout "Stated Animation Setup" width:272 height:254
|
|
(
|
|
local stateIdx = getattrindex "Gta Object" "animState"
|
|
|
|
-- Filter-function for "add state" pickbutton:
|
|
fn addFilter obj =
|
|
(
|
|
while (0!=findItem allowedStateClasses (getattrclass obj)) and (not isKindOf obj.parent Container) and (obj.parent != undefined) do obj = obj.parent
|
|
|
|
(0!=findItem allowedStateClasses (getattrclass obj)) and
|
|
(
|
|
(gRsStatedAnimTool.currAnim == undefined) or
|
|
(
|
|
(findItem gRsStatedAnimTool.currAnim.objectArray obj) == 0
|
|
)
|
|
)
|
|
)
|
|
|
|
local animBtnWidth = 64
|
|
local btnPadding = 5
|
|
|
|
group "Animation Attributes:"
|
|
(
|
|
edittext groupNameBox "AnimGroup:" align:#left offset:[0,0] across:2 width:(RsStatedAnimRollout.width - 62)
|
|
hyperLink help "Help?" align:#right offset:[0,0] address:"https://devstar.rockstargames.com/wiki/index.php/Simulated_Map_Animations#Art_setup" color:(color 0 0 255)
|
|
label txdLbl "TXD names:" align:#left across:2
|
|
dropdownList ddlTXDs "" enabled:false pos:(txdLbl.pos + [65, -2]) width:(RsStatedAnimRollout.width - 118)
|
|
label lblCompression "Compression" align:#left across:2
|
|
dropdownList ddlCompression "" enabled:false width:(RsStatedAnimRollout.width - 118) offset:[-85,0]
|
|
|
|
button btnFindAnim "Find Anim" width:60 height:18 align:#left offset:[0,1] across:4
|
|
button deleteAttrButton "Delete Anim" width:70 height:18 pos:(btnFindAnim.pos + [60 + btnPadding, 0])
|
|
button proxyButton "Build proxy" height:18 pos:(deleteAttrButton.pos + [70 + btnPadding, 0])
|
|
checkbox loopCheckBox "Looped Anim" offset:[0,3] align:#right
|
|
)
|
|
|
|
local stateBtnWidth = 78
|
|
group "States: (rightclick to change type)"
|
|
(
|
|
listbox stateObjList "" height:5 offset:[-0,-3]
|
|
|
|
pickbutton btnAddState "Add state" filter:addFilter width:stateBtnWidth height:18 offset:[-6,-3] align:#left across:4
|
|
button btnAddIPLState "Add IMAP state" width:(stateBtnWidth+5) height:18 offset:[4,-3]
|
|
button btnAddSelStates "Add selected" width:stateBtnWidth height:18 offset:[3,-3]
|
|
button btnDelState "Remove state" width:stateBtnWidth height:18 offset:[6,-3] align:#right enabled:false
|
|
)
|
|
|
|
local stateCtrls = #(deleteAttrButton, proxyButton, loopCheckBox, stateObjList, btnAddState, btnAddSelStates, btnDelState)
|
|
local editStateCtrls = #(btnDelState)
|
|
|
|
fn getCompressionDefinitions =
|
|
(
|
|
local compFolder = RsConfigGetEtcDir() + "config/anim/compression_templates/*Stated_Anim*"
|
|
local compressionFiles = getFiles compFolder
|
|
for fi=1 to compressionFiles.count do
|
|
(
|
|
compressionFiles[fi] = getFilenameFile compressionFiles[fi]
|
|
)
|
|
ddlCompression.items = compressionFiles
|
|
)
|
|
|
|
fn GetCurrentAnimCompression =
|
|
(
|
|
local searchPattern = "*Default*"
|
|
if undefined!=gRsStatedAnimTool.currAnim then
|
|
searchPattern = gRsStatedAnimTool.currAnim.compression
|
|
local newSel = 1
|
|
for fi=1 to ddlCompression.items.count do
|
|
(
|
|
if matchPattern ddlCompression.items[fi] pattern:searchPattern then
|
|
newSel = fi
|
|
)
|
|
ddlCompression.selection = newSel
|
|
)
|
|
|
|
fn setCtrlsEnabled =
|
|
(
|
|
stateCtrls.enabled = false
|
|
|
|
if not (matchPattern groupNameBox.text pattern:"DEFAULT") then
|
|
(
|
|
stateCtrls.enabled = true
|
|
editStateCtrls.enabled = (stateObjList.selection != 0)
|
|
ddlCompression.enabled = true
|
|
)
|
|
else
|
|
ddlCompression.enabled = false
|
|
|
|
ddlTXDs.enabled = (ddlTXDs.items.count != 0)
|
|
)
|
|
|
|
fn updateList =
|
|
(
|
|
stateObjList.selection = 0
|
|
|
|
stateObjList.items = gRsStatedAnimTool.getObjectNames()
|
|
groupNameBox.text = gRsStatedAnimTool.getCurrentAnimGroupName()
|
|
loopCheckBox.checked = gRsStatedAnimTool.currAnim.looped
|
|
ddlTXDs.items = gStatedAnimFoundTXDs
|
|
ddlCompression.selected = gRsStatedAnimTool.currAnim.compression
|
|
|
|
setCtrlsEnabled()
|
|
)
|
|
|
|
fn selChanged =
|
|
(
|
|
if not gRsStatedAnimTool.selectionChanged() do
|
|
(
|
|
gRsStatedAnimTool.Deinit()
|
|
)
|
|
GetCurrentAnimCompression()
|
|
updateList()
|
|
)
|
|
|
|
fn enableCallbacks flag =
|
|
(
|
|
if flag then
|
|
(
|
|
callbacks.removeScripts id:#RsStatedAnimTool
|
|
callbacks.addScript #filePreOpenProcess "gRsStatedAnimTool.Deinit(); RsStatedAnimRollout.updateList()" id:#RsStatedAnimTool
|
|
callbacks.addscript #selectionSetChanged "RsStatedAnimRollout.selChanged()" id:#RsStatedAnimTool
|
|
)
|
|
else
|
|
(
|
|
callbacks.removeScripts id:#RsStatedAnimTool
|
|
)
|
|
)
|
|
|
|
----------------------------
|
|
-- "STATES" EVENTS --
|
|
----------------------------
|
|
fn getStateObj =
|
|
(
|
|
gRsStatedAnimTool.currAnim.objectArray[stateObjList.selection]
|
|
)
|
|
|
|
fn listSelected val =
|
|
(
|
|
enableCallbacks false
|
|
suspendEditing()
|
|
gRsStatedAnimTool.selectObject val
|
|
resumeEditing()
|
|
enableCallbacks true
|
|
)
|
|
|
|
on stateObjList selected val do
|
|
(
|
|
editStateCtrls.enabled = true
|
|
listSelected val
|
|
)
|
|
|
|
on stateObjList rightClick val do
|
|
(
|
|
rcmenu RsMenu_stateListChangeType
|
|
(
|
|
menuItem itmTitle "Set State Type:" enabled:false
|
|
menuItem itmStart "Start" checked:false
|
|
menuItem itmAnim "Animation" checked:false
|
|
menuItem itmEnd "End" checked:false
|
|
|
|
fn setState stateName =
|
|
(
|
|
local stateObj = getStateObj()
|
|
local stateIdx = getattrindex (getattrclass stateObj) "animState"
|
|
setAttr stateObj stateIdx stateName
|
|
|
|
gRsStatedAnimTool.currAnim.Reset()
|
|
selChanged()
|
|
stateObjList.selection = findItem gRsStatedAnimTool.currAnim.objectArray stateObj
|
|
editStateCtrls.enabled = true
|
|
)
|
|
|
|
on itmStart picked do (setState "Start")
|
|
on itmAnim picked do (setState "Animation")
|
|
on itmEnd picked do (setState "End")
|
|
|
|
on RsMenu_stateListChangeType open do
|
|
(
|
|
local obj = getStateObj()
|
|
local stateIdx = getattrindex (getattrclass obj) "animState"
|
|
local stateName = getAttr obj stateIdx
|
|
case stateName of
|
|
(
|
|
"Start":(itmStart.checked = true)
|
|
"Animation":(itmAnim.checked = true)
|
|
"End":(itmEnd.checked = true)
|
|
)
|
|
)
|
|
)
|
|
|
|
stateObjList.selection = val
|
|
listSelected val
|
|
popUpMenu RsMenu_stateListChangeType
|
|
)
|
|
|
|
on btnFindAnim pressed do
|
|
(
|
|
RsAnimFinder.create()
|
|
)
|
|
on btnAddState picked obj do
|
|
(
|
|
gRsStatedAnimTool.addObject obj
|
|
setCtrlsEnabled()
|
|
updateList()
|
|
)
|
|
on btnAddIPLState pressed do
|
|
(
|
|
try(
|
|
CreateDialog RsIPLGroupCreation 250 80 modal:true
|
|
)catch(
|
|
DestroyDialog RsIPLGroupCreation
|
|
)
|
|
if undefined!=gLatestIplGroupDummy then
|
|
(
|
|
gRsStatedAnimTool.addObject gLatestIplGroupDummy
|
|
setCtrlsEnabled()
|
|
)
|
|
updateList()
|
|
)
|
|
|
|
on btnAddSelStates pressed do
|
|
(
|
|
for obj in selection do
|
|
(
|
|
while (getattrclass obj.parent == "Gta Object") and (not isKindOf obj.parent Container) and (obj.parent != undefined) do obj = obj.parent
|
|
|
|
if (getattrclass obj == "Gta Object") and
|
|
(
|
|
(gRsStatedAnimTool.currAnim == undefined) or
|
|
(
|
|
(findItem gRsStatedAnimTool.currAnim.objectArray obj) == 0
|
|
)
|
|
) do
|
|
(
|
|
gRsStatedAnimTool.addObject obj
|
|
)
|
|
)
|
|
|
|
setCtrlsEnabled()
|
|
updateList()
|
|
)
|
|
on btnDelState pressed do
|
|
(
|
|
if (stateObjList.selection != 0) do
|
|
(
|
|
if (gRsStatedAnimTool.deleteObject stateObjList.selection) do
|
|
(
|
|
updateList()
|
|
)
|
|
)
|
|
)
|
|
|
|
-----------------------------------------------
|
|
-- "SAVE TO OBJ ATTRIBS" EVENTS --
|
|
-----------------------------------------------
|
|
on ddlTXDs selected num do
|
|
(
|
|
gRsStatedAnimTool.setTxdNames ddlTXDs.selected
|
|
gRsStatedAnimTool.Deinit()
|
|
if undefined!=selection[1] then
|
|
select selection[1]
|
|
)
|
|
on groupNameBox entered newText do
|
|
(
|
|
gRsStatedAnimTool.changeAnimGroup newText
|
|
|
|
if (gRsStatedAnimTool.currAnim.objectArray.count != 0) do
|
|
(
|
|
selChanged()
|
|
)
|
|
|
|
setCtrlsEnabled()
|
|
)
|
|
on deleteAttrButton pressed do
|
|
(
|
|
gRsStatedAnimTool.deleteAttributes()
|
|
selChanged()
|
|
)
|
|
on loopCheckBox changed val do
|
|
(
|
|
gRsStatedAnimTool.setLooped val
|
|
)
|
|
on proxyButton pressed do
|
|
(
|
|
gRsStatedAnimTool.buildProxy groupNameBox.text
|
|
)
|
|
on ddlCompression selected val do
|
|
(
|
|
if undefined!=gRsStatedAnimTool.currAnim then
|
|
(
|
|
local success = gRsStatedAnimTool.setCompression ddlCompression.selected
|
|
)
|
|
)
|
|
|
|
----------------------------
|
|
-- ROLLOUT EVENTS --
|
|
----------------------------
|
|
on RsStatedAnimRollout open do
|
|
(
|
|
enableCallbacks true
|
|
getCompressionDefinitions()
|
|
GetCurrentAnimCompression()
|
|
selChanged()
|
|
)
|
|
on RsStatedAnimRollout close do
|
|
(
|
|
enableCallbacks false
|
|
gRsStatedAnimTool.Deinit()
|
|
)
|
|
)
|
|
|
|
rollout RsStatedAnimTools "Stated Animation Tools" width:272 height:260
|
|
(
|
|
hyperlink help "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Simulated_Map_Animations#Skinning_tools" offset:[0,-4] align:#right color:(color 0 0 255)
|
|
|
|
local btnWidth = 200
|
|
button buttCreateSkin "Create skinned version" offset:[0,-4] width:btnWidth tooltip:"All objects of the animation are supposed to be in one hirarchy setup as if to export for an animated object. Select one of the objects of the animation and click this button. The material of the selection is the multimaterial that's put on the end result."
|
|
button buttWeldSkins "Weld two selected skinned meshes" width:btnWidth tooltip:"This function assumes two or more objects to be selected of which at least one is skinned. The first object is the reference for the result's name and material. Also, if the first object's bone hirarchy is set up for export, all the bones of the objects to be attached will get welded into the hirarchy."
|
|
button buttRootReplace "Replace meshes with dummies" width:btnWidth tooltip:"Replaces all selected nodes with dummy objects of same size, name and transform."
|
|
button buttResetObjects "Reset selected objects" width:btnWidth tooltip:"All seelcted objects get their according attributes reset."
|
|
button buttSplitHier "Split up hierarchies" width:(btnWidth-40) tooltip:"Children of selected nodes will get relinked to new nodes." across:2 offset:[56,0]
|
|
spinner spnHierLimit "" type:#integer width:40 tooltip:"upper limit of nodes linked to new parents" range:[1,127,127] offset:[-30,3]
|
|
button btnAttrSearch "Select objs with group attr set" width:btnWidth
|
|
|
|
on buttCreateSkin pressed do
|
|
(
|
|
local sel = selection[1]
|
|
if undefined!=sel then
|
|
bakeAnimToPoints &sel
|
|
)
|
|
on buttWeldSkins pressed do
|
|
(
|
|
weldSelection()
|
|
)
|
|
on buttRootReplace pressed do
|
|
(
|
|
RsRootReplace()
|
|
)
|
|
on buttResetObjects pressed do
|
|
(
|
|
::gRsStatedAnimTool.ResetAttributes ($selection as array)
|
|
)
|
|
on buttSplitHier pressed do
|
|
(
|
|
splitHierarchy $ maxNumObjs:spnHierLimit.value
|
|
)
|
|
|
|
on btnAttrSearch pressed do
|
|
(
|
|
local idxGroupName = getattrindex "Gta Object" "groupName"
|
|
for o in objects where
|
|
("Gta Object" == getattrclass o) and
|
|
("DEFAULT"!=getattr o idxGroupName)
|
|
do
|
|
selectMore o
|
|
)
|
|
)
|
|
|
|
global RsStatedAnimFloater = newRolloutFloater "Stated Anim Tools" 340 450
|
|
addRollout RsStatedAnimRollout RsStatedAnimFloater
|
|
addRollout RsStatedAnimTools RsStatedAnimFloater
|