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

1123 lines
32 KiB
Plaintext
Executable File

-- Fragment tuning glabals
filein "rockstar/export/settings.ms"
filein "pipeline/helpers/physics.ms"
filein "pipeline/util/xml.ms"
global gFragEditMode = #default
global gCpyChildren = false
global gReloadFileMode = true
global gPrvntCollSel = true
global copyPasteErrors = ""
global gPresetElem = undefined
fn getPresetNames =
(
local presetNames = #("none")
local xmlDoc = XmlDocument()
xmlDoc.load (RsProjectGetCommonDir() + "/data/fragment.xml")
xmlDoc.ParseIntoMaxscripthierarchy()
gPresetElem = xmlDoc.maxXmlObject.children[2].findChild withName:"BreakPresets"
if undefined!=gPresetElem then
for presetItem in gPresetElem.children do
(
local nameChild = presetItem.children[1]
append presetNames nameChild.textValue
)
return presetNames
)
fn updatePresetProps theRollout presetName groupName =
(
if undefined==theRollout or undefined==gPresetElem then
return false
local thePreset = undefined
for presetItem in gPresetElem.children while undefined==thePreset do
(
local nameChild = presetItem.children[1]
if nameChild.textValue==presetName then
(
thePreset = presetItem
)
)
if undefined!=thePreset then
(
for presetProp in thePreset.children do
(
-- first the control
local theControl = undefined
for ctrl in theRollout.controls while undefined==theControl do
(
if 0!=findItem #(GroupStartControl, GroupEndControl) (classof ctrl) then
continue
if (0==stricmp ctrl.name presetProp.tagname) then
theControl = ctrl
)
if undefined!=theControl then
(
try
(
theControl.value = (presetProp.attrs.item "value") as float
case classof theControl of
(
SpinnerControl:theControl.changed theControl.value
CheckboxControl:theControl.changed theControl.value
)
)
catch
(
print (getCurrentException())
)
)
)
)
)
struct sRsFragAttribLUT
(
------------------------------------------------------------------------
-- FRAG ATTRIBS
------------------------------------------------------------------------
-- identifier --standard export --readable name -default value selection-data change-callback
RsFragAttribLUT = #(
#("minMoveForce", true, "Min force to move me", 0),
#("artAssetID", true, undefined, -1),
#("attachBottomEnd", true, undefined, 0),
#("estimatedCacheSize", true, undefined, 0),
#("estimatedArticulatedCacheSize", true, undefined, 0),
#("cloneBoundPartsInCache", true, undefined, 0),
#("unbrokenCGOffset", true, undefined, #(0,0,0)),
#("unbrokenElasticity", true, "Unbroken elasticity", 0),
#("gravityFactor", true, undefined, 1.0),
#("buoyancyFactor", true, undefined, 1.0),
#("breakImpulseSourceTypeFlags", true, undefined, 0),
#("dampingLinearC", true, undefined, #(0.02,0.02,0.02)),
#("dampingLinearV", true, undefined, #(0.02,0.02,0.02)),
#("dampingLinearV2", true, undefined, #(0.01,0.01,0.01)),
#("dampingAngularC", true, undefined, #(0.02,0.02,0.02)),
#("dampingAngularV", true, undefined, #(0.02,0.02,0.02)),
#("dampingAngularV2", true, undefined, #(0.01,0.01,0.01)),
#("selfCollisionCount", true, undefined, 0)
),
------------------------------------------------------------------------
-- GROUP ATTRIBS
------------------------------------------------------------------------
RsGroupAttribLUT = #(
#("strength", true, "Break Strength", 100.0),
#("forceTransmissionScaleUp", true, "ForceTransmission Up", 0.25),
#("forceTransmissionScaleDown", true, "ForceTransmission Down", 0.25),
#("jointStiffness", true, undefined, 0),
#("minSoftAngle1", true, undefined, -1),
#("maxSoftAngle1", true, undefined, 1),
#("maxSoftAngle2", true, undefined, 1),
#("maxSoftAngle3", true, undefined, 1),
#("rotationSpeed", true, undefined, 0),
#("rotationStrength", true, undefined, 0),
#("restoringStrength", true, undefined, 0),
#("restoringMaxTorque", true, undefined, 0),
#("latchStrength", true, "Contraint latch strength", 0),
#("disappearsWhenDead", true, "Disappear when dead", false),
#("madeOfGlass", true, "Made of glass", false),
#("minDamageForce", true, "MinDamage force", 0),
#("damageHealth", true, "Intial damage health", 0),
#("weaponHealth", true, "Weapon health", 0),
#("weaponScale", true, "Weapons", 1.0),
#("vehicleScale", true, "Vehicles", 1.0),
#("pedScale", true, "Peds", 1.0),
#("ragdollScale", true, "Ragdolls", 1.0),
#("explosionScale", true, "Explosions", 1.0),
#("objectScale", true, "Objects", 1.0),
#("preset", true, "Preset", "none", ::getPresetNames, "updatePresetProps")
),
------------------------------------------------------------------------
-- CHILD ATTRIBS
------------------------------------------------------------------------
RsChildAttribLUT = #(
#("pristineMass", true, "Pristine mass", calculateMass),
#("damagedMass", true, "Damaged mass", calculateMass)
),
RsAttribLUT = RsFragAttribLUT + RsGroupAttribLUT + RsChildAttribLUT,
-- accessors
fn getDefault key =
(
for tuple in RsAttribLUT do
(
if (tuple[1]==key) then return tuple[3]
)
return undefined
),
fn getDefaultExport key =
(
for tuple in RsAttribLUT do
(
if (tuple[1]==key) then return tuple[2]
)
return false
),
fn getDataFunc key =
(
for tuple in RsAttribLUT do
(
if (tuple[1]==key) then return tuple[5]
)
return undefined
),
fn getCallback key =
(
for tuple in RsAttribLUT do
(
if (tuple[1]==key) then return tuple[6]
)
return undefined
),
fn getValue key =
(
if gFragEditMode==#verbose then return key
for tuple in RsAttribLUT do
(
if (tuple[1]==key) then
(
return tuple[3]
)
)
return undefined
)
)
global gRsFragAttribLUT = sRsFragAttribLUT()
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- data holding/processing structs
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
struct sFragGroup
(
groupName = "fragments",
parentGroup = undefined,
groupValues = #(),
groupArray = #(),
childArray = #()
)
struct sFragChild
(
childName = "dummyname",
parentGroup = undefined,
childValues = #()
)
#typeBool
#typeScalar
#typeArray
#typeString
#typeScope
struct sAttrValue
(
attrName,
attrValue,
attrType,
attrExportFlag = false,
fn copyme =
(
local newOne = sAttrValue()
newOne.attrName = attrName
newOne.attrValue = attrValue
newOne.attrType = attrType
newOne.attrExportFlag = attrExportFlag
return newOne
)
)
struct sFragTuner
(
tuneArray = #(),
currFrag = 0.0,
currFragName = "initial",
currFragRoot = sFragGroup(),
currFragGroup = currFragRoot,
currObj,
copyFragHier = undefined,
childObj,
groupObj,
fragObj,
isFrag,
isGroup,
currHirarchyErrors = "",
-- fn RsTrimAndChopLine idx currLine = (
-- filteredLine = filterstring currLine " "
--
-- if filteredLine[idx] != undefined then (
-- --currTrimLine = RsGetTrimParamFromString filteredLine[idx]
-- currLine = RsRemoveSpacesFromString filteredLine[idx]
-- currLine = RsRemoveTabsFromString currLine
-- )
--
-- return currLine
-- ),
-- fn RsGetTrimParamFromString currLine = (
--
-- currLine = RsRemoveSpacesFromString currLine
-- currLine = RsRemoveTabsFromString currLine
--
-- return currLine
-- ),
fn SetReloadFileMode val =
(
gReloadFileMode = val
if undefined!=::RsButtonRoll then
(
::RsButtonRoll.checkReloadFile.checked = val
)
),
fn ResetFragTune =
(
currHirarchyErrors = undefined
currFragRoot = sFragGroup()
currFragGroup = currFragRoot
currFragname = ""
SetReloadFileMode true
),
fn GetTunePath =
(
RsConfigGetAssetsDir() + "fragments/" + currFragName + ".tune"
),
fn RetrieveIndentation obj = (
indentation = 1
while classof(obj.parent) != UndefinedClass do (
obj = obj.parent
indentation = indentation + 1
)
return indentation + 1
),
fn isObjInCurrHierarchy obj =
(
do
(
if (matchpattern obj.name pattern:("*"+currFragName+"*")) then
return true
obj = obj.parent
) while undefined!=obj
return false
),
--------------------------------------------------------------------------
-- Extract hierarchical information from selected object
--------------------------------------------------------------------------
fn DetermineObject = (
isFrag = false
isGroup = false
sel = selection as array
obj = sel[1]
if obj != Undefined then (
if "GtaObject"==(getattrclass obj) or Point == (classof obj) and obj.parent != undefined then (
groupObj = obj
isGroup = true
groupName = obj.name
)
else if "GtaObject"==(getattrclass obj) then (
fragIndex = getattrindex "Gta Object" "Is Fragment"
if getattr obj fragIndex == true then (
isFrag = true
isGroup = false
)
)
-- get the absolute parent
while classof(obj.parent) != UndefinedClass do (
obj = obj.parent
)
fragObjName = tolower obj.name
-- Get rid of any of the skinned helper nodes
if matchPattern fragObjName pattern:"dummy_*" then
fragObjName = substring fragObjName 7 fragObjName.count
if matchPattern fragObjName pattern:"mover_*" then
fragObjName = substring fragObjName 7 fragObjName.count
if matchPattern fragObjName pattern:"root_*" then
fragObjName = substring fragObjName 7 fragObjName.count
if matchPattern fragObjName pattern:"main_*" then
fragObjName = substring fragObjName 7 fragObjName.count
--getting rid of suffix
local fragStringIndex = findString fragObjName "_frag_"
if fragStringIndex!=undefined then
fragObjName = substring fragObjName 1 (fragStringIndex-1)
currFragName = fragObjName
)
),
fn dumpGroup theGroup theFile indentDepth isRoot =
(
local indent = ""
local borderindent = ""
local i=0
while i<indentDepth do
(
borderindent+="\t"
i+=1
)
i=0
while i<indentDepth+1 do
(
indent+="\t"
i+=1
)
if isRoot then
format ("fragments\n{\n") to:theFile
else
format (borderindent+"group "+theGroup.groupName+"\t\t\t{\n") to:theFile
for val in theGroup.groupValues where val.attrExportFlag do
(
case val.attrType of
(
#typeScalar:
(
if (findString val.attrName "Mass")!=undefined then
format (indent+val.attrName+" all\t"+(val.attrValue as string)+"\n") to:theFile
else
format (indent+val.attrName+"\t"+(val.attrValue as string)+"\n") to:theFile
)
#typeArray:
(
format (indent+val.attrName+"\t"+(val.attrValue[1] as string)+"\t"+(val.attrValue[2] as string)+"\t"+(val.attrValue[3] as string)+"\n") to:theFile
)
#typeBool:
(
if val.attrValue then
format (indent+val.attrName+"\n") to:theFile
)
#typeString:
(
if undefined!=val.attrValue then
format (indent+val.attrName+"\t<"+(val.attrValue as string)+">\n") to:theFile
)
)
)
for c in theGroup.childArray do
(
format (indent+"child\t\t\t\t{\n") to:theFile
local childIndent = ""
i=0
while i<indentDepth+2 do
(
childIndent+="\t"
i+=1
)
for val in c.childvalues where val.attrExportFlag do
(
case val.attrType of
(
#typeScalar:
(
if (findString val.attrName "Mass")!=undefined then
format (childIndent+val.attrName+" all\t"+(val.attrValue as string)+"\n") to:theFile
else
format (childIndent+val.attrName+"\t"+(val.attrValue as string)+"\n") to:theFile
)
#typeArray:
(
format (childIndent+val.attrName+"\t"+(val.attrValue[1] as string)+"\t"+(val.attrValue[2] as string)+"\t"+(val.attrValue[3] as string)+"\n") to:theFile
)
#typeString:
(
if undefined!=val.attrValue then
format (indent+val.attrName+"\t<"+(val.attrValue as string)+">\n") to:theFile
)
)
)
format (indent+"}\n") to:theFile
)
for grp in theGroup.groupArray do
(
dumpGroup grp theFile (indentDepth+1) false
)
format (borderindent+"}\n") to:theFile
),
fn WriteOutAttrib tunePath = (
sel = selection as array
try
(
if tunePath != "" then (
tuneFile = openFile tunePath mode:"w+"
gRsPerforce.add_or_edit tunePath
if tuneFile != undefined and sel != undefined then
(
dumpGroup currFragRoot tuneFile 0 true
close tuneFile
SetReloadFileMode true
return true
)
messagebox ("Error writing to " + tunePath + ". Check to see file is writable.")
close tuneFile
return false
--commandLine = "attrib +r " + tunePath
--doscommand commandLine
)
messagebox "no valid path"
close tuneFile
)
catch(
messagebox ("Fragment save error: "+getCurrentException())
)
return false
),
--------------------------------------------------------------------------------------------------------------------------------------------------
-- Parsing attributes
--------------------------------------------------------------------------------------------------------------------------------------------------
fn ParseNextSubString str =
(
if str[1]=="<" then
return #(substring str 2 (str.count-2))
--find first intersector
local intersector = " "
local firstWhite = findString str " "
local firstTab = findString str "\t"
if firstWhite==undefined or (firstTab!=undefined and firstTab<firstWhite) then
intersector = "\t"
back = filterstring str intersector
-- local found = false
-- look for tag brackets
-- for i=1 to back.count where matchpattern back[i] pattern:"<*" while not found do
-- (
-- back[i] = substring back[i] 2 back[i].count
-- -- join them together
-- local ended = false
-- while not ended do
-- (
-- back[i] = join back[i] back[i+1]
-- if matchpattern back[i+1] pattern:"*>*" then
-- ended = true
-- deleteItem back (i=1)
-- )
-- found = true
-- )
return back
),
fn ParseNameAndValueFromString str =
(
while str[1]=="\t" or str[1]==" " do str = substring str 2 str.count
back = sAttrValue()
-- parse name
local nameParseStep = ParseNextSubString str
back.attrName = nameParseStep[1]
-- parse Value
back.attrValue = undefined
back.attrType = #typeScope
if nameParseStep[2]!=undefined then
(
local valueParseStep = ParseNextSubString (substring str (nameParseStep[1].count+2) str.count)
if valueParseStep.count>0 then
(
if (valueParseStep[1] as number)!=undefined then
(
if valueParseStep.count>1 then
(
back.attrType = #typeArray
back.attrValue = valueParseStep
)
else
(
back.attrType = #typeScalar
back.attrValue = valueParseStep[1]
)
)
else
(
if valueParseStep.count>1 and valueParseStep[1]=="all" then -- masses on children have the all suffix
(
back.attrType = #typeScalar
back.attrValue = valueParseStep[2]
)
else
(
back.attrType = #typeString
back.attrValue = valueParseStep[1]
)
)
)
)
else
(
back.attrType = #typeBool
back.attrValue =true
)
back.attrExportFlag = true
return back
),
--------------------------------------------------------------------------
-- Stream in tune data
--------------------------------------------------------------------------
fn ReadInAttrib tunePath = (
local currScope = #("root")
sel = selection as array
currObj = sel[1]
tuneFile = openFile tunePath
local addedGroupValues = #()
if tuneFile != undefined then
(
while eof tuneFile == false do (
currentLine = readLine tuneFile
-- remove trailing spaces
local nameAndValueTuple = ParseNameAndValueFromString currentLine
prefix = nameAndValueTuple.attrName
value = nameAndValueTuple.attrValue
if prefix == "}" then
(
if currScope.count>0 then
(
if currScope[currScope.count]=="groupScope" then
(
for groupVal in gRsFragAttribLUT.RsGroupAttribLUT do
(
if 0== (for v in currFragGroup.groupValues where v.attrName==groupVal[1] collect v).count then
(
local defaultNameAndValueTuple = sAttrValue attrName:groupVal[1] attrValue:groupVal[4] attrExportFlag:false
if (classof groupVal[4] == number) then defaultNameAndValueTuple.attrType = #typeScalar
else if (classof groupVal[4] == booleanclass) then defaultNameAndValueTuple.attrType = #typeBool
else if (classof groupVal[4] == array) then defaultNameAndValueTuple.attrType = #typeArray
else if (classof groupVal[4] == string) then defaultNameAndValueTuple.attrType = #typeString
append currFragGroup.groupValues defaultNameAndValueTuple
)
)
addedGroupValues = #()
currFragGroup = currFragGroup.parentGroup
)
deleteItem currScope currScope.count
)
-- try( print ("< "+currScope[currScope.count]+", "+(currScope.count as string)) )catch()
continue
)
else if prefix == "group" then
(
groupName = value
append currScope "groupScope"
local formerFragGroup = currFragGroup
currFragGroup = sFragGroup()
currFragGroup.parentGroup = formerFragGroup
currFragGroup.groupName = groupName
append formerFragGroup.groupArray currFragGroup
)
else if prefix == "child" then
(
currChild = sFragChild()
append currScope "childScope"
currentLine = readLine tuneFile
local nameAndValueTuple = ParseNameAndValueFromString currentLine
append currChild.childValues nameAndValueTuple
currentLine = readLine tuneFile
local nameAndValueTuple = ParseNameAndValueFromString currentLine
append currChild.childValues nameAndValueTuple
append currFragGroup.childArray currChild
)
else if
not matchPattern prefix pattern:"fragments" and
not matchPattern prefix pattern:"{" then
(
-- tis a value
append addedGroupValues nameAndValueTuple.attrName
append currFragGroup.groupValues nameAndValueTuple
)
)
close tuneFile
return true
)
else
return false
),
--------------------------------------------------------------------------
-- Create the tune hierarchy to show from actual scene data
--------------------------------------------------------------------------
fn ParseNameAndValueFromDefault val obj =
(
back = sAttrValue()
back.attrName = val[1]
back.attrValue = val[4]
if MAXScriptFunction == (classof back.attrValue) then
back.attrValue = back.attrValue(obj)
back.attrType = \
if (classof back.attrValue) == BooleanClass then #typeBool \
else if (superClassOf back.attrValue)==number then #typeScalar \
else if (classof back.attrValue)==array then #typeArray \
else #typeString
back.attrExportFlag = val[2]
return back
),
fn createGroup sceneNode =
(
local formerFragGroup = currFragGroup
currFragGroup = sFragGroup()
currFragGroup.parentGroup = formerFragGroup
currFragGroup.groupName = sceneNode.name
if matchPattern currFragGroup.groupName pattern:"*_frag_*" then
(
local index = findString currFragGroup.groupName "_frag_"
currFragGroup.groupName = replace currFragGroup.groupName index 6 ""
)
-- print currFragGroup.groupName
if undefined!=formerFragGroup then
(
append formerFragGroup.groupArray currFragGroup
-- print formerFragGroup.groupName
-- print formerFragGroup.groupArray.count
)
-- create attributes
for val in gRsFragAttribLUT.RsGroupAttribLUT do
(
local nameAndValueTuple = ParseNameAndValueFromDefault val sceneNode
append currFragGroup.groupValues nameAndValueTuple
)
-- bounds data
local childBounds = for c in sceneNode.children where "Gta Collision"==(getAttrClass c) collect c
for b in childBounds do
(
currChild = sFragChild()
for val in gRsFragAttribLUT.RsChildAttribLUT do
(
local nameAndValueTuple = ParseNameAndValueFromDefault val b
append currChild.childValues nameAndValueTuple
)
append currFragGroup.childArray currChild
)
-- child data
local childMeshes = for c in sceneNode.children where "Gta Object"==(getAttrClass c) or Point == (classof c) collect c
for c in childMeshes do
(
createGroup c
)
if undefined!=formerFragGroup then
currFragGroup = formerFragGroup
return true
),
fn CreateHierarachyFromNodes saveImmediately:false overWriteIfExistent:false = (
local obj = selection[1]
if obj == undefined then
(
messagebox "Select an object!"
return false
)
local fragName = obj.name
local fragNode = getNodeByName (obj.name+"_frag_")
local foundRootFragmentBone = false
if undefined!=fragNode then
(
obj = fragNode
if (undefined != obj.modifiers[#Skin]) then
(
rootBone = rexGetSkinRootBone obj
if rootBone != undefined then
(
obj = rootBone
local mainRootBone = obj.children[1]
if (mainRootBone != undefined and matchPattern mainRootBone.name pattern:"main_*") then
(
obj = mainRootBone.children[1]
if (obj == undefined) then messagebox "Frag is not setup correctly with skinning!"
else foundRootFragmentBone = true
)
)
)
)
-- If we found the root fragment bone then we don't need to try to find the parent in the hierarchy
if not foundRootFragmentBone then
(
while obj.parent != undefined do obj = obj.parent
)
select obj
local tunePath = GetTunePath()
if doesFileExist tunePath then
(
print ("file already exists:"+tunePath)
if not overWriteIfExistent then
return false
)
ResetFragTune()
DetermineObject()
currFragGroup = sFragGroup()
currFragGroup.parentGroup = undefined
currFragGroup.groupName = "root"
currFragRoot = currFragGroup
for val in gRsFragAttribLUT.RsFragAttribLUT do
(
local nameAndValueTuple = ParseNameAndValueFromDefault val fragNode
append currFragGroup.groupValues nameAndValueTuple
)
print "create hierarchy"
if not (createGroup obj) then
return false
SetReloadFileMode false
if saveImmediately then ::gFragTuner.WriteFragTuneData()
return true
),
--------------------------------------------------------------------------
-- Hierarchy manipulation
--------------------------------------------------------------------------
fn findGroup root grpName =
(
if matchPattern grpName pattern:"*_frag_*" then
(
grpName = substring grpName 1 ((findString grpName "_frag_")-1)
)
-- if currFragname == grpName then return currFragRoot
if root.groupName==grpName then return root
for grp in root.groupArray do
(
local back = findGroup grp grpName
if back != undefined then return back
)
return undefined
),
fn setGroupValueDirect grp valName newVal arrayIndex:undefined setAllChildren:false =
(
if grp!=undefined then
(
for val in grp.groupValues do
(
if val.attrName==valname then
(
-- print (val.attrName+" set to "+newVal as string)
if arrayindex!=undefined then
(
val.attrValue[arrayIndex] = newVal
)
else if
-- Array==(classof val.attrValue) and
Array==(classof newVal) then
(
val.attrValue = deepCopy newVal
)
else
(
val.attrValue = newVal
)
)
)
if setAllChildren then
for g in grp.groupArray do
setGroupValueDirect g valName newVal arrayIndex:arrayIndex setAllChildren:setAllChildren
)
),
fn setGroupValue grpName valName newVal arrayIndex setAllChildren:false =
(
local grp = findGroup currFragRoot grpName
setGroupValueDirect grp valName newVal arrayIndex:arrayIndex
),
fn setGroupExportFlag grpName valName newVal =
(
local grp = findGroup currFragRoot grpName
if grp!=undefined then
(
for val in grp.groupValues do
if val.attrName==valname then
(
print (val.attrName+" exportflag set to "+newVal as string)
val.attrExportFlag = newVal
)
)
),
fn setChildValueDirect grp childIndex valName newVal =
(
childIndex = childIndex as integer
if grp!=undefined and grp.childArray.count>=childIndex then
(
for val in grp.childArray[childIndex].childValues do
if val.attrName==valname then val.attrValue = newVal
)
),
fn setChildValue grpName childIndex valName newVal =
(
local grp = findGroup currFragRoot grpName
setChildValueDirect grp childIndex valName newVal
),
fn checkGroup theGroup sceneNode =
(
-- if theGroup.groupName=="fragments" then
-- if theGroup.childArray.count != sceneNode then
local childMeshes = for c in sceneNode.children where "Gta Object"==(getAttrClass c) or Point == (classof c) collect c
local childBounds = for c in sceneNode.children where "Gta Collision"==(getAttrClass c) collect c
if theGroup.groupArray.count != childMeshes.count then
(
currHirarchyErrors = (sceneNode.name+"'s child mesh count "+(childMeshes.count as string)+" not equal to "+(theGroup.groupName)+"'s group count "+(theGroup.groupArray.count as string))
return false
)
if theGroup.childArray.count != childBounds.count then
(
currHirarchyErrors = (sceneNode.name+"'s child collision count "+(childBounds.count as string)+" not equal to "+(theGroup.groupName)+"'s child count "+(theGroup.childArray.count as string))
return false
)
for grp in theGroup.groupArray do
(
if not (checkGroup grp (getNodeByName grp.groupName)) then
return false
)
return true
),
fn checkFragHirarchy obj =
(
local fragNode = getNodeByName (obj.name+"_frag_")
if undefined!=fragNode then obj = fragNode
return (checkGroup currFragGroup obj)
),
fn PopulateFragTuner = (
if $selection.count<=0 then
(
::ResetRollouts undefined
return false
)
local isSameFragment = false
local obj = selection[1]
if gPrvntCollSel and "Gta Collision"==(getAttrClass obj) and undefined!=obj.parent then
(
obj = obj.parent
select obj
return false
)
if undefined!=obj then
(
currFragGroup = findGroup currFragRoot obj.name
isSameFragment = undefined!=currFragGroup
)
local isHierarchyValid = true
if gReloadFileMode or not isSameFragment then
(
ResetFragTune()
-- create new
DetermineObject()
-- currFragRoot.groupName = currFragName
local tunePath = GetTunePath()
if ReadInAttrib tunePath then
(
currFragGroup = findGroup currFragRoot obj.name
)
else
isHierarchyValid = false
)
if isHierarchyValid then
(
if undefined==currFragGroup then currFragGroup = currFragRoot
checkFragHirarchy obj
if undefined!=ResetRollouts then
ResetRollouts currFragGroup.groupName
)
else
(
if undefined!=ResetRollouts then
ResetRollouts undefined
)
return true
),
fn RefreshUI =
(
if undefined!=::RsTreeViewRoll then
::RsTreeViewRoll.reset()
local selectionValid = PopulateFragTuner()
if selectionValid and undefined!=::RsTreeViewRoll then
(
::RsTreeViewRoll.updateTV currFragRoot currFragGroup
::RsFragRoll.setFragName currFragname
)
),
fn WriteFragTuneData = (
tunePath = GetTunePath()
WriteOutAttrib tunePath
),
-------------------------------------------------------------------------------------
-- copy hierarchy
-------------------------------------------------------------------------------------
fn copyGroup theGroup =
(
local newGroup = sFragGroup()
for val in theGroup.groupValues where val.attrExportFlag do
(
append newGroup.groupValues (val.copyMe())
)
for c in theGroup.childArray do
(
local newChild = sFragChild()
append newGroup.childArray newChild
for val in c.childvalues where val.attrExportFlag do
(
append newChild.childvalues (val.copyMe())
)
)
if gCpyChildren then
for grp in theGroup.groupArray do
(
append newGroup.groupArray (copyGroup grp)
)
return newGroup
),
fn copyFragHierarchy =
(
copyFragHier = copyGroup (if gCpyChildren then currFragRoot else currFragGroup)
),
--------------------------------------------------------------------------
fn pasteGroup fromGroup toGroup=
(
for fromVal in fromGroup.groupValues do
(
setGroupValueDirect toGroup fromVal.attrName fromVal.attrValue
)
for childIndex=1 to fromGroup.childArray.count do
(
if toGroup.childArray.count<childIndex then
(
copyPasteErrors += ("less collision meshes on "+toGroup.groupName+" than children from copybuffer\n")
exit
)
else
(
local fromChild = fromGroup.childArray[childIndex]
local toChild = toGroup.childArray[childIndex]
for fromVal in fromChild.childvalues do
(
setChildValueDirect toGroup childIndex fromVal.attrName fromVal.attrValue
)
)
)
for grpindex=1 to fromGroup.groupArray.count do
(
if toGroup.groupArray.count<grpindex then
(
copyPasteErrors += ("less submeshes on "+toGroup.groupName+" than groups from copybuffer\n")
exit
)
else
(
pasteGroup fromGroup.groupArray[grpindex] toGroup.groupArray[grpindex]
)
)
return newGroup
),
fn pasteFragHierarchy =
(
if selection.count<=0 then
(
messagebox "Select at least one object (and less than 10) to copy values to."
return false
)
if undefined==copyFragHier then
(
messagebox "No values copied yet."
return false
)
local selectionCopy = deepCopy (selection as array)
for obj in selectionCopy do
(
-- select submesh
select obj
CreateHierarachyFromNodes()
-- re-select for correct group selection
select obj
copyPasteErrors = ""
(pasteGroup copyFragHier (if gCpyChildren then currFragRoot else currFragGroup))
if copyPasteErrors != "" then messagebox copyPasteErrors
WriteFragTuneData()
)
RefreshUI()
),
----------------------------------------------------------------------------
-- ticking
fn tickGroup theGroup tickType =
(
for val in theGroup.groupValues do
(
case tickType of
(
#ticknone: val.attrExportFlag = false
#tickall: val.attrExportFlag = true
#tickdefault: val.attrExportFlag = (gRsFragAttribLUT.getDefaultExport val.attrName)
#tickinvert: val.attrExportFlag = not val.attrExportFlag
)
)
for c in theGroup.childArray do
(
for val in c.childvalues do
(
case tickType of
(
#ticknone: val.attrExportFlag = false
#tickall: val.attrExportFlag = true
#tickdefault: val.attrExportFlag = (undefined!=(gRsFragAttribLUT.getDefault val.attrName))
#tickinvert: val.attrExportFlag = not val.attrExportFlag
)
)
)
if gCpyChildren then
for grp in theGroup.groupArray do
(
tickGroup grp tickType
)
),
fn tickFragHierarchy tickType =
(
tickGroup (if gCpyChildren then currFragRoot else currFragGroup) tickType
::ResetRollouts currFragGroup.groupName
)
) -- struct sFragTuner
global gFragTuner = sFragTuner()