491 lines
17 KiB
Plaintext
Executable File
491 lines
17 KiB
Plaintext
Executable File
|
|
----------------------------------------------------------------------------------------------------
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
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
|
|
|