---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- struct RAGEClothDataEntryUI ( spinCtrl, multiLabel ) struct RAGEClothDataEnty ( userName, vDataChn, defaultVal, uiEntry ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- --Note the vDataChn values must remain the same as what REX is expecting to export global RAGEClothChannelTable = #( (RAGEClothDataEnty userName:"Pin" vDataChn:10 defaultVal:0.0), \ (RAGEClothDataEnty userName:"Pin Radius" vDataChn:11 defaultVal:0.0), \ (RAGEClothDataEnty userName:"Pin Ramp" vDataChn:12 defaultVal:0.0), \ (RAGEClothDataEnty userName:"Edge Compression" vDataChn:13 defaultVal:0.25), \ (RAGEClothDataEnty userName:"Bend Spring Length" vDataChn:14 defaultVal:0.5), \ (RAGEClothDataEnty userName:"Bend Spring Strength" vDataChn:15 defaultVal:0.7) \ ) fn GetChannelTableEntryByUserName userName = ( for i in 1 to RAGEClothChannelTable.count do ( if(RAGEClothChannelTable[i].userName == userName) then return i ) return undefined ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- fn GetValidObjectSelection showMsgs:true = ( selClass = classof $ if($ == undefined) then ( return undefined ) if(selClass == ObjectSet) then ( if(showMsgs) then MessageBox "More than one object selected. Please select a single object to operate on." title:"RAGE Cloth Editor Error" return undefined ) else ( if( (selClass != Editable_Mesh) And (selClass != Editable_Poly) ) then ( print("$ = "+ $ as string) print("selClass = "+ selClass as string) if(showMsgs) then MessageBox "Selected object is not an EditablePoly or EditableMesh object, operation aborted." title:"RAGE Cloth Editor Error" return undefined ) ) return $ ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- fn GetChannelSupport object channelIndex = ( if ( classOf object == Editable_Mesh ) then ( return ( meshop.getVDataChannelSupport object channelIndex ) ) else if ( classOf object == Editable_Poly ) then ( return ( polyop.getVDataChannelSupport object channelIndex ) ) return false ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- fn SetChannelSupport object channelIndex isSupported = ( if ( classOf object == Editable_Mesh ) then ( meshop.setVDataChannelSupport object channelIndex isSupported ) else if ( classOf object == Editable_Poly ) then ( polyop.setVDataChannelSupport object channelIndex isSupported ) ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- fn GetChannelValue object channelIndex vertIndex = ( if ( classOf object == Editable_Mesh ) then ( return ( meshop.getVDataValue object channelIndex vertIndex ) ) else if ( classOf object == Editable_Poly ) then ( return ( polyop.getVDataValue object channelIndex vertIndex ) ) return undefined ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- fn SetChannelValue object channelIndex vertIndex value = ( if ( classOf object == Editable_Mesh ) then ( meshop.setVDataValue object channelIndex vertIndex value ) else if ( classOf object == Editable_Poly ) then ( polyop.setVDataValue object channelIndex vertIndex value ) ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- rollout RageClothChannelTuning "Cloth Channel Tuning" width:280 height:200 ( hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Rage_Cloth_Editor#What_Do_All_The_Numbers_Mean" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255) local curObjSel = undefined local curObjParamChangeHandler = undefined label lbl7 "Selected Object :" pos:[7,14] width:87 height:16 label selObjectLabel "(none)" pos:[93,14] width:150 height:18 spinner pinSpin "" pos:[137,40] width:109 height:16 range:[0,1,0] scale:1.0 spinner pinRadiusSpin "" pos:[137,63] width:109 height:16 range:[0,1,0] scale:0.01 spinner pinRampSpin "" pos:[137,86] width:109 height:16 range:[0,1,0] scale:0.01 spinner edgeCompressionSpin "" pos:[137,109] width:109 height:16 range:[0,1,0] scale:0.01 spinner bendSpringLengthSpin "" pos:[137,132] width:109 height:16 range:[0,1,0] scale:0.01 spinner bendSpringStrengthSpin "" pos:[137,155] width:109 height:16 range:[0,1,0] scale:0.01 label pinMultiLbl " " pos:[253,40] width:20 height:14 label pinRadiusMultiLbl " " pos:[253,63] width:20 height:14 label pinRampMultiLbl " " pos:[253,86] width:20 height:14 label edgeCompressionMultiLbl " " pos:[253,109] width:20 height:14 label bendSpringLengthMultiLbl " " pos:[253,132] width:20 height:14 label bendSpringStrengthMultiLbl " " pos:[253,155] width:20 height:14 label pinLbl "Pin" pos:[18,40] width:80 height:14 label pinRadiusLbl "Pin Radius" pos:[18,63] width:109 height:14 label pinRampLbl "Pin Ramp" pos:[18,86] width:109 height:14 label edgeCompressionLbl "Edge Compression" pos:[18,109] width:109 height:14 label bendSpringLengthLbl "Bend Spring Length" pos:[18,132] width:109 height:14 label bendSpringStrengthLbl "Bend Spring Strength" pos:[18,155] width:109 height:14 fn UpdateInterface = ( -- Make sure all the data is there selObject = GetValidObjectSelection() if(selObject != undefined) then ( nVerts = selObject.vertices.count for i in 1 to RAGEClothChannelTable.count do ( if(not (GetChannelSupport selObject RAGEClothChannelTable[i].vDataChn)) then ( SetChannelSupport selObject RAGEClothChannelTable[i].vDataChn true for vIdx in 1 to nVerts do ( SetChannelValue selObject RAGEClothChannelTable[i].vDataChn vIdx RAGEClothChannelTable[i].defaultVal ) ) ) ) -- Update the interface if(curObjSel != undefined) then ( --Update the selected object name selObjectLabel.text = curObjSel.name --Update the tuning controls if(curObjSel.selectedVerts.count > 0) then ( for i in 1 to RAGEClothChannelTable.count do ( if(curObjSel.selectedVerts.count > 1) then ( RAGEClothChannelTable[i].uiEntry.multiLabel.text = "*" ) else ( RAGEClothChannelTable[i].uiEntry.multiLabel.text = " " ) if(GetChannelSupport curObjSel RAGEClothChannelTable[i].vDataChn) then ( RAGEClothChannelTable[i].uiEntry.spinCtrl.enabled = true RAGEClothChannelTable[i].uiEntry.spinCtrl.value = GetChannelValue curObjSel RAGEClothChannelTable[i].vDataChn curObjSel.selectedVerts[1].index ) else ( RAGEClothChannelTable[i].uiEntry.spinCtrl.enabled = false ) ) ) else ( for i in 1 to RAGEClothChannelTable.count do ( RAGEClothChannelTable[i].uiEntry.multiLabel.text = " " RAGEClothChannelTable[i].uiEntry.spinCtrl.enabled = false RAGEClothChannelTable[i].uiEntry.spinCtrl.value = 0.0 ) ) ) else ( selObjectLabel.text = "(none)" for i in 1 to RAGEClothChannelTable.count do ( RAGEClothChannelTable[i].uiEntry.multiLabel.text = " " RAGEClothChannelTable[i].uiEntry.spinCtrl.enabled = false RAGEClothChannelTable[i].uiEntry.spinCtrl.value = 0.0 ) ) ) fn OnObjectSubSelectionChangedHandler = ( UpdateInterface() ) fn UpdateObjectChangeHandlers = ( if(curObjParamChangeHandler != undefined) then ( format "Removing current change handler\n" deleteChangeHandler curObjParamChangeHandler ) if(curObjSel != undefined) then ( format "Adding change handler to %\n" curObjSel.name curObjParamChangeHandler = when select curObjSel changes do (OnObjectSubSelectionChangedHandler()) ) ) fn OnSelectionSetChangedEventCallback = ( curObjSel = GetValidObjectSelection showMsgs:false UpdateObjectChangeHandlers() UpdateInterface() ) fn SetClothTuningValuesOnSelectedVerts vChnId fValue = ( if(curObjSel != undefined) then ( if(GetChannelSupport curObjSel vChnId) then ( nSelVerts = curObjSel.selectedVerts.count for i in 1 to nSelVerts do ( SetChannelValue curObjSel vChnId curObjSel.selectedVerts[i].index fValue ) ) ) ) --Wanted to make these dynamic, but I can't get dynamic event handlers to work... on RageClothChannelTuning open do ( RAGEClothChannelTable[1].uiEntry = (RAGEClothDataEntryUI spinCtrl:pinSpin multiLabel:pinMultiLbl) RAGEClothChannelTable[2].uiEntry = (RAGEClothDataEntryUI spinCtrl:pinRadiusSpin multiLabel:pinRadiusMultiLbl) RAGEClothChannelTable[3].uiEntry = (RAGEClothDataEntryUI spinCtrl:pinRampSpin multiLabel:pinRampMultiLbl) RAGEClothChannelTable[4].uiEntry = (RAGEClothDataEntryUI spinCtrl:edgeCompressionSpin multiLabel:edgeCompressionMultiLbl) RAGEClothChannelTable[5].uiEntry = (RAGEClothDataEntryUI spinCtrl:bendSpringLengthSpin multiLabel:bendSpringLengthMultiLbl ) RAGEClothChannelTable[6].uiEntry = (RAGEClothDataEntryUI spinCtrl:bendSpringStrengthSpin multiLabel:bendSpringStrengthMultiLbl ) curObjSel = GetValidObjectSelection showMsgs:false UpdateObjectChangeHandlers() UpdateInterface() callbacks.addScript #selectionSetChanged "RageClothChannelTuning.OnSelectionSetChangedEventCallback()" id:#TestRolloutSelSetChangedEventId ) on RageClothChannelTuning close do ( callbacks.removeScripts #selectionSetChanged id:#TestRolloutSelSetChangedEventId if(curObjParamChangeHandler != undefined) then ( format "Removing current change handler\n" deleteChangeHandler curObjParamChangeHandler ) ) on pinSpin changed newValue do ( SetClothTuningValuesOnSelectedVerts RAGEClothChannelTable[1].vDataChn newValue ) on pinRadiusSpin changed newValue do ( SetClothTuningValuesOnSelectedVerts RAGEClothChannelTable[2].vDataChn newValue ) on pinRampSpin changed newValue do ( SetClothTuningValuesOnSelectedVerts RAGEClothChannelTable[3].vDataChn newValue ) on edgeCompressionSpin changed newValue do ( SetClothTuningValuesOnSelectedVerts RAGEClothChannelTable[4].vDataChn newValue ) on bendSpringLengthSpin changed newValue do ( SetClothTuningValuesOnSelectedVerts RAGEClothChannelTable[5].vDataChn newValue ) on bendSpringStrengthSpin changed newValue do ( SetClothTuningValuesOnSelectedVerts RAGEClothChannelTable[6].vDataChn newValue ) ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- rollout RageClothChannelManage "Cloth Channel Management" width:280 height:100 ( hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Rage_Cloth_Editor" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255) button createChnButton "Create Channel" pos:[18,59] width:105 height:21 button removeChnButton "Remove Channel" pos:[145,58] width:105 height:21 dropDownList channelDrop "Cloth Tuning Channel" pos:[20,9] width:233 height:40 on RageClothChannelManage open do ( tmpItemArr = #() for i in 1 to RAGEClothChannelTable.count do ( append tmpItemArr RAGEClothChannelTable[i].userName ) channelDrop.Items = tmpItemArr ) on createChnButton pressed do ( selObject = GetValidObjectSelection() if(selObject != undefined) then ( SetChannelSupport selObject RAGEClothChannelTable[channelDrop.selection].vDataChn true nVerts = selObject.vertices.count for vIdx in 1 to nVerts do ( SetChannelValue selObject RAGEClothChannelTable[channelDrop.selection].vDataChn vIdx RAGEClothChannelTable[channelDrop.selection].defaultVal ) RageClothChannelTuning.UpdateInterface() ) ) on removeChnButton pressed do ( selObject = GetValidObjectSelection() if(selObject != undefined) then ( SetChannelSupport selObject RAGEClothChannelTable[channelDrop.selection].vDataChn false ) RageClothChannelTuning.UpdateInterface() ) ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- rollout RageClothChannelDebug "Cloth Channel Debugging" width:280 height:193 ( dropdownList channelDrop "Cloth Tuning Channel" pos:[27,9] width:233 height:40 groupBox grp1 "Select By Tuning Value" pos:[10,61] width:263 height:109 dropDownList compDrop "Comparison Type" pos:[27,85] width:227 height:40 items:#("Exactly", "Less Than", "Greater Than") spinner selValueSpin "" pos:[137,135] width:104 height:16 range:[0,1,0.0] scale:0.01 button compSelectButton "Select" pos:[31,133] width:98 height:19 fn Exactly valA valB = ( return (valA == valB) ) fn LessThan valA valB = ( return (valA < valB) ) fn GreaterThan valA valB = ( return (valA > valB) ) fn SelectVertsByTuningValue vChnId fValue compOper = ( selObject = GetValidObjectSelection() if(selObject == undefined) then return false subobjectLevel = 1 if ( not (GetChannelSupport selObject vChnId) ) then ( selObject.selectedVerts = #() ) else ( selVertArray = #() nVerts = selObject.vertices.count for vIdx in 1 to nVerts do ( chnValue = GetChannelValue selObject vChnId vIdx if( (compOper chnValue fValue) == true ) then ( append selVertArray vIdx ) ) selObject.selectedVerts = selVertArray ) ) on RageClothChannelDebug open do ( tmpItemArr = #() for i in 1 to RAGEClothChannelTable.count do ( append tmpItemArr RAGEClothChannelTable[i].userName ) channelDrop.Items = tmpItemArr ) on compSelectButton pressed do ( case compDrop.selected of ( "Exactly" : SelectVertsByTuningValue RAGEClothChannelTable[channelDrop.selection].vDataChn selValueSpin.value Exactly "Less Than" : SelectVertsByTuningValue RAGEClothChannelTable[channelDrop.selection].vDataChn selValueSpin.value LessThan "Greater Than" : SelectVertsByTuningValue RAGEClothChannelTable[channelDrop.selection].vDataChn selValueSpin.value GreaterThan ) ) ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- rollout RageClothChannelDisplay "Cloth Channel View" width:280 height:193 ( dropdownList channelDrop "Cloth Tuning Channel" pos:[27,9] width:233 height:40 on RageClothChannelDisplay open do ( tmpItemArr = #() for i in 1 to RAGEClothChannelTable.count do ( append tmpItemArr RAGEClothChannelTable[i].userName ) channelDrop.Items = tmpItemArr print (channelDrop as string) manipulateMode = true ) on RageClothChannelDisplay close do ( manipulateMode = false ) on channelDrop selected item do ( manipulateMode = false manipulateMode = true ) ) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- try CloseRolloutFloater RAGEClothEditorFloater catch() RAGEClothEditorFloater = newRolloutFloater "RAGE Cloth Editor" 300 485 -- addRollout RageClothChannelManage RAGEClothEditorFloater addRollout RageClothChannelTuning RAGEClothEditorFloater addRollout RageClothChannelDebug RAGEClothEditorFloater addRollout RageClothChannelDisplay RAGEClothEditorFloater fileIn "ClothManip.ms" manipulateMode = false manipulateMode = true