Files
gtav-src/tools_ng/dcc/current/max2012/scripts/rage/RageClothEditor.ms
T
2025-09-29 00:52:08 +02:00

566 lines
20 KiB
Plaintext
Executable File

manipulateMode = false
filein "pipeline/helpers/cloth_helpers.ms"
try
DestroyDialog RsClothLodEditorRoll
catch()
filein "pipeline/ui/RSClothLodEditor.ms"
filein "pipeline/ui/RSClothLiveLink.ms"
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
fn GetValidObjectSelection &msg:undefined =
(
selClass = classof $
if($ == undefined) then
(
return undefined
)
if(selClass == ObjectSet) then
(
if(undefined!=msg) then
msg = "Please select a single object to operate on."
return undefined
)
else
(
if( (selClass != Editable_Mesh) And (selClass != Editable_Poly) ) then
(
print("$ = "+ $ as string)
print("selClass = "+ selClass as string)
if(undefined!=msg) then
msg = "Selection is not an EditablePoly or EditableMesh object."
return undefined
)
-- AJM: Add in vert limit check
if ($.numverts > 1000) do (
if(undefined!=msg) then
msg = "Object has more than 1000 verts."
return undefined
)
)
return $
)
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
rollout RageClothChannelTuning "Cloth Channel Tuning" width:280 height:231
(
HyperLink lnkHelp "Help?" pos:[239,7] width:28 height:15 address:"https://devstar.rockstargames.com/wiki/index.php/Rage_Cloth_Editor#What_Do_All_The_Numbers_Mean" color:(color 0 0 255) hovercolor:(color 0 0 255) visitedcolor:(color 0 0 255)
local curObjSel = undefined
local curObjParamChangeHandler = undefined
local controlWidth = 50
local controlHeight = 16
local varChannelWidth = 60
local labelWidth = 109
local spinnerOffset = [-90,0]
local controlOffset = [-20,0]
local multiLabelOffset = [-40,0]
label lbl7 "Selected Object :" width:87 height:16 across:2
label selObjectLabel "(none)" width:150 height:16
label vertSelCount "" height:20
label nameLbl "Channel name" width:labelWidth height:14 across:3 align:#left
label controlLbl "| Edit" width:controlWidth height:16 offset:[0,0]
spinner variationSpin "| Variation" width:varChannelWidth height:16 range:[0,9,gCurrVariationChannel] offset:[30,0] type:#integer
label pinLbl RAGEClothChannelTable[1].userName width:labelWidth height:14 across:2 align:#left
checkbox pinSpin "" width:controlWidth height:16 scale:1 offset:controlOffset
label pinRadiusLbl RAGEClothChannelTable[2].userName width:labelWidth height:controlHeight across:4 align:#left
spinner pinRadiusSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[2].range scale:0.01 offset:[25,0]
button pinRadiusVarUse "+" tooltip:"Use Variation Channel" offset:[25,0] enabled:false width:controlHeight height:controlHeight
button pinRadiusVarDismiss "x" tooltip:"Dismiss Variation Channel" offset:[-23,0] enabled:false width:controlHeight height:controlHeight
label pinRampLbl RAGEClothChannelTable[3].userName width:labelWidth height:14 across:2 align:#left
spinner pinRampSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[3].range scale:0.01 offset:spinnerOffset
label weightLbl RAGEClothChannelTable[7].userName width:labelWidth height:14 across:2 align:#left
spinner weightSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[7].range scale:0.01 offset:spinnerOffset
label edgeCompressionLbl RAGEClothChannelTable[4].userName width:labelWidth height:14 across:2 align:#left
spinner edgeCompressionSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[4].range scale:0.01 offset:spinnerOffset
label bendSpringLengthLbl RAGEClothChannelTable[5].userName width:labelWidth height:14 across:2 align:#left
spinner bendSpringLengthSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[5].range scale:0.01 offset:spinnerOffset
label bendSpringStrengthLbl RAGEClothChannelTable[6].userName width:labelWidth height:14 across:2 align:#left
spinner bendSpringStrengthSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[6].range scale:0.01 offset:spinnerOffset
label cmbDynPinLbl RAGEClothChannelTable[10].userName width:labelWidth height:14 across:2 align:#left
dropdownlist cmbDynPin "" width:controlWidth height:16 offset:controlOffset items:RAGEClothChannelTable[10].range
group "Mapping"
(
label mappingTolLbl RAGEClothChannelTable[8].userName width:labelWidth height:14 across:2 align:#left
spinner mappingTolSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[8].range scale:0.001 offset:spinnerOffset
label mappingErrorLbl RAGEClothChannelTable[9].userName width:labelWidth height:14 across:2 align:#left
spinner mappingErrorSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[9].range scale:0.001 offset:spinnerOffset
button btnMappingValidation "Validate Mapping" width:250
)
label inflationScaleLbl RAGEClothChannelTable[11].userName width:labelWidth height:14 across:2 align:#left
spinner inflationScaleSpin "" width:controlWidth height:16 range:RAGEClothChannelTable[11].range scale:0.01 offset:spinnerOffset
label customEdgeLbl RAGEClothChannelTable[12].userName width:labelWidth height:14 across:2 align:#left
checkbox customEdgeCheck "" width:controlWidth height:16 scale:1 offset:controlOffset
fn SetControlValue ctrl val =
(
if isProperty ctrl "value" then
ctrl.value = val
else if isProperty ctrl "state" then
ctrl.state = (val>0.0)
else if isProperty ctrl "selection" then
ctrl.selection = (val+1)
)
fn ResetInterface =
(
for i in 1 to RAGEClothChannelTable.count do
(
RAGEClothChannelTable[i].uiEntry.spinCtrl.enabled = false
SetControlValue RAGEClothChannelTable[i].uiEntry.spinCtrl 0.0
)
)
fn SetVariationChannelControlsEnabled whichCtrl whichChannel state =
(
case whichCtrl of
(
#use:
(
if undefined!=RAGEClothChannelTable[whichChannel].uiEntry.varChannelUse then
RAGEClothChannelTable[whichChannel].uiEntry.varChannelUse.enabled = state
)
#dismiss:
(
if undefined!=RAGEClothChannelTable[whichChannel].uiEntry.varChannelDismiss then
RAGEClothChannelTable[whichChannel].uiEntry.varChannelDismiss.enabled = state
)
)
)
fn UpdateInterface =
(
-- Make sure all the data is there
local useVariationChannel = variationSpin.value>0
local msg = "invalid"
curObjSel = GetValidObjectSelection msg:&msg
-- only do this automatically if not having a variation channel selected
if(curObjSel != undefined and not useVariationChannel) then
(
nVerts = curObjSel.vertices.count
vertSelCount.text = ("Number of vertices selected: "+curObjSel.selectedVerts.count as string)
for i in 1 to RAGEClothChannelTable.count do
(
EnableAndInitMapChannel curObjSel i
)
)
-- 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(GetChannelSupport curObjSel (RsGetClothTuningChannel i)) then
(
-- If live update is enabled only pin radii can be modified
if (RageClothLiveLink.btnLiveUpdate.state == off or i == 2) then
(
RAGEClothChannelTable[i].uiEntry.spinCtrl.enabled = true
)
else
(
RAGEClothChannelTable[i].uiEntry.spinCtrl.enabled = false
)
SetControlValue RAGEClothChannelTable[i].uiEntry.spinCtrl (GetChannelValue curObjSel (RsGetClothTuningChannel i) curObjSel.selectedVerts[1].index)
if useVariationChannel then
(
SetVariationChannelControlsEnabled #use i false
SetVariationChannelControlsEnabled #dismiss i true
)
)
else
(
RAGEClothChannelTable[i].uiEntry.spinCtrl.enabled = false
if useVariationChannel then
(
SetVariationChannelControlsEnabled #use i true
SetVariationChannelControlsEnabled #dismiss i false
)
)
if not useVariationChannel then
(
SetVariationChannelControlsEnabled #use i false
SetVariationChannelControlsEnabled #dismiss i false
)
)
)
else
(
ResetInterface()
)
update curObjSel
)
else
(
selObjectLabel.text = msg
Resetinterface()
)
-- Update the live link interface as well
RageClothLiveLink.UpdateInterface(curObjSel)
)
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()
UpdateObjectChangeHandlers()
UpdateInterface()
)
fn SetClothTuningValuesOnVerts vChnId fValue selVerts =
(
if(curObjSel != undefined) then
(
if(GetChannelSupport curObjSel vChnId) then
(
nSelVerts = selVerts.count
for i in 1 to nSelVerts do
(
SetChannelValue curObjSel vChnId selVerts[i].index fValue
)
)
)
)
fn SetClothTuningValuesOnSelectedVerts vChnId fValue =
(
if(curObjSel != undefined) then
(
if(GetChannelSupport curObjSel vChnId) then
(
SetClothTuningValuesOnVerts vChnId fValue curObjSel.selectedVerts
)
)
)
--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)
RAGEClothChannelTable[2].uiEntry = (RAGEClothDataEntryUI spinCtrl:pinRadiusSpin varChannelUse:pinRadiusVarUse varChannelDismiss:pinRadiusVarDismiss)
RAGEClothChannelTable[3].uiEntry = (RAGEClothDataEntryUI spinCtrl:pinRampSpin)
RAGEClothChannelTable[4].uiEntry = (RAGEClothDataEntryUI spinCtrl:edgeCompressionSpin)
RAGEClothChannelTable[5].uiEntry = (RAGEClothDataEntryUI spinCtrl:bendSpringLengthSpin)
RAGEClothChannelTable[6].uiEntry = (RAGEClothDataEntryUI spinCtrl:bendSpringStrengthSpin)
RAGEClothChannelTable[7].uiEntry = (RAGEClothDataEntryUI spinCtrl:weightSpin)
RAGEClothChannelTable[8].uiEntry = (RAGEClothDataEntryUI spinCtrl:mappingTolSpin)
RAGEClothChannelTable[9].uiEntry = (RAGEClothDataEntryUI spinCtrl:mappingErrorSpin)
RAGEClothChannelTable[10].uiEntry = (RAGEClothDataEntryUI spinCtrl:cmbDynPin)
RAGEClothChannelTable[11].uiEntry = (RAGEClothDataEntryUI spinCtrl:inflationScaleSpin)
RAGEClothChannelTable[12].uiEntry = (RAGEClothDataEntryUI spinCtrl:customEdgeCheck)
curObjSel = GetValidObjectSelection()
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 (RsGetClothTuningChannel 1) (if newValue then 1.0 else 0.0) )
on pinRadiusSpin changed newValue do
(
SetClothTuningValuesOnSelectedVerts(RsGetClothTuningChannel 2) newValue
-- Update live link values
RageClothLiveLink.UpdatePinRadiiForSelection curObjSel.selectedVerts newValue
)
on pinRampSpin changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 3) newValue )
on edgeCompressionSpin changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 4) newValue )
on bendSpringLengthSpin changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 5) newValue )
on bendSpringStrengthSpin changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 6) newValue )
on weightSpin changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 7) newValue )
on mappingTolSpin changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 8) newValue )
on mappingErrorSpin changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 9) newValue )
on cmbDynPin selected newValue do
(
newValue = newValue-1 -- shift to make 0 or > 0
SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 10) newValue
)
on btnMappingValidation pressed do
(
ValidateMappingTolerances()
)
on inflationScaleSpin changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 11) newValue )
on customEdgeCheck changed newValue do
( SetClothTuningValuesOnSelectedVerts (RsGetClothTuningChannel 12) (if newValue then 1.0 else 0.0) )
------------------------
-- Variation controls
on variationSpin changed val do
(
gCurrVariationChannel = val
UpdateInterface()
)
on pinRadiusVarUse pressed do
(
EnableAndInitMapChannel (GetValidObjectSelection()) 2
UpdateInterface()
)
on pinRadiusVarDismiss pressed do
(
DisableAndDenitMapChannel (GetValidObjectSelection()) 2
UpdateInterface()
)
)
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
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
(
curObjSel = GetValidObjectSelection()
-- if(curObjSel != undefined) then
-- (
-- SetChannelSupport curObjSel (RsGetClothTuningChannel channelDrop.selection) true
-- nVerts = curObjSel.vertices.count
-- for vIdx in 1 to nVerts do
-- (
-- SetChannelValue curObjSel (RsGetClothTuningChannel channelDrop.selection) vIdx RAGEClothChannelTable[channelDrop.selection].defaultVal
-- )
-- RageClothChannelTuning.UpdateInterface()
-- )
)
on removeChnButton pressed do
(
curObjSel = GetValidObjectSelection()
if(curObjSel != undefined) then
(
SetChannelSupport curObjSel RAGEClothChannelTable[channelDrop.selection].vDataChn false
)
RageClothChannelTuning.UpdateInterface()
)
)
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
rollout RageClothChannelDebug "Cloth Channel Selection" 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 =
(
curObjSel = GetValidObjectSelection()
if(curObjSel == undefined) then
return false
subobjectLevel = 1
if ( not (GetChannelSupport curObjSel vChnId) ) then
(
curObjSel.selectedVerts = #()
)
else
(
selVertArray = #()
nVerts = curObjSel.vertices.count
for vIdx in 1 to nVerts do
(
chnValue = GetChannelValue curObjSel vChnId vIdx
if( (compOper chnValue fValue) == true ) then
(
append selVertArray vIdx
)
)
curObjSel.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 (RsGetClothTuningChannel channelDrop.selection) selValueSpin.value Exactly
"Less Than" : SelectVertsByTuningValue (RsGetClothTuningChannel channelDrop.selection) selValueSpin.value LessThan
"Greater Than" : SelectVertsByTuningValue (RsGetClothTuningChannel channelDrop.selection) selValueSpin.value GreaterThan
)
)
)
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
rollout RageClothChannelDisplay "Cloth Channel View" width:280 height:193
(
dropdownList channelDrop "Cloth Tuning Channel" pos:[27,9] width:233 height:40
checkbox chckRenderMeshDebugDraw "Show render/simulation mesh link" pos:[27,53] checked:true across:2
spinner spnRenderMeshDebugDrawOffset "" range:[0.0,1.0,0.01] scale:0.01
checkbox chckShowOnlySel "Show only on selected verts" checked:true
on chckRenderMeshDebugDraw changed val do
(
local obj = RageClothChannelTuning.curObjSel
if undefined!=obj then
obj.pos = obj.pos
)
on spnRenderMeshDebugDrawOffset changed val do
(
local obj = RageClothChannelTuning.curObjSel
obj.pos = obj.pos
)
on RageClothChannelDisplay open do
(
tmpItemArr = #()
for i in 1 to RAGEClothChannelTable.count do
(
append tmpItemArr RAGEClothChannelTable[i].userName
)
channelDrop.Items = tmpItemArr
manipulateMode = true
)
on RageClothChannelDisplay close do
(
manipulateMode = false
)
on channelDrop selected item do
(
manipulateMode = false
manipulateMode = true
)
on chckShowOnlySel changed val do
(
local obj = RageClothChannelTuning.curObjSel
if undefined!=obj then
update obj
redrawViews()
)
)
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
try CloseRolloutFloater RAGEClothEditorFloater catch()
RAGEClothEditorFloater = newRolloutFloater "RAGE Cloth Editor" 300 835
-- addRollout RageClothChannelManage RAGEClothEditorFloater
addRollout RageClothChannelTuning RAGEClothEditorFloater
addRollout RageClothChannelDebug RAGEClothEditorFloater
addRollout RageClothChannelDisplay RAGEClothEditorFloater
addRollout RsClothLodEditorRoll RAGEClothEditorFloater
addRollout RageClothLiveLink RAGEClothEditorFloater
fileIn "ClothManip.ms"
manipulateMode = true