Files
2025-09-29 00:52:08 +02:00

313 lines
8.8 KiB
Plaintext
Executable File

-- Natural Motion bounds and constraints loader
-- 26/5/2006
-- by Greg Smith
-- by Marissa Warner-Wu
filein "pipeline/util/xml.ms"
filein "pipeline/util/string.ms"
-- Removes formatting for XML element text
fn RsRemoveFormatting str = (
retstr = ""
for i = 1 to str.count do (
if findstring ".|-_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" str[i] != undefined then (
retstr = retstr + str[i]
)
)
retstr
)
fn RsSpaceToUnderscore str = (
retstr = ""
for i = 1 to str.count do (
if str[i] == " " then (
retstr = retstr + "_"
) else (
retstr = retstr + str[i]
)
)
retstr
)
fn RsNmLoadBound nmFilename = (
-- Load the XML file
xmlDoc = XmlDocument()
xmlDoc.init()
xmlDoc.load nmFilename
nmRoot = xmlDoc.document.DocumentElement
-- Setup bounds variables
partName = ""
partType = #none
partRadius = 0
partHeight = 0
partDimX = 0
partDimY = 0
partDimZ = 0
partMat = matrix3 0
partPath = ""
-- Check that this is a valid XML
if nmRoot.name == "MODEL" then (
rootChildren = nmRoot.childnodes
-- Iterate through the parts
for i = 0 to ( rootChildren.Count - 1 ) do (
-- Read and set info for this part
currentChild = rootChildren.itemof(i)
partChildren = currentChild.childnodes
for i = 0 to ( partChildren.Count - 1 ) do (
subPartChild = partChildren.itemof(i)
if subPartChild.name == "name" then (
partName = RsRemoveFormatting subPartChild.innertext
print partName
)
else if subPartChild.name == "full_path" then (
partPath = RsRemoveFormatting subPartChild.innertext
)
else if subPartChild.name == "local" then (
matChildren = subPartChild.childnodes
if matChildren.Count == 16 then (
-- Set the matrix values
for i = 0 to ( matChildren.Count - 1 ) do (
matChild = matChildren.itemof(i)
value = RsRemoveFormatting matChild.innertext
if matChild.name == "m00" then (
partMat.row1.x = value as number
format "partMat.row1.x = % " partMat.row1.x
)
if matChild.name == "m01" then (
partMat.row1.y = value as number
format "partMat.row1.y = % " partMat.row1.y
)
if matChild.name == "m02" then (
partMat.row1.z = value as number
format "partMat.row1.z = % \n" partMat.row1.z
)
if matChild.name == "m10" then (
partMat.row2.x = value as number
format "partMat.row2.x = % " partMat.row2.x
)
if matChild.name == "m11" then (
partMat.row2.y = value as number
format "partMat.row2.y = % " partMat.row2.y
)
if matChild.name == "m12" then (
partMat.row2.z = value as number
format "partMat.row2.z = % \n" partMat.row2.z
)
if matChild.name == "m20" then (
partMat.row3.x = value as number
format "partMat.row3.x = % " partMat.row3.x
)
if matChild.name == "m21" then (
partMat.row3.y = value as number
format "partMat.row3.y = % " partMat.row3.y
)
if matChild.name == "m22" then (
partMat.row3.z = value as number
format "partMat.row3.z = % \n" partMat.row3.z
)
if matChild.name == "m30" then (
partMat.row4.x = value as number
format "partMat.row4.x = % " partMat.row4.x
)
if matChild.name == "m31" then (
partMat.row4.y = value as number
format "partMat.row4.y = % " partMat.row4.y
)
if matChild.name == "m32" then (
partMat.row4.z = value as number
format "partMat.row4.z = % \n\n" partMat.row4.z
)
)
)
) --if subPartChild.name == "local"
else if subPartChild.name == "Volume" then (
volType = subPartChild.firstchild
if volType.name == "Capsule" then (
partType = #capsule
)
else if volType.name == "Box" then (
partType = #box
)
volChildren = volType.childnodes
for i = 0 to ( volChildren.Count - 1 ) do (
volChild = volChildren.itemof(i)
value = RsRemoveFormatting volChild.innertext
if volChild.name == "radius" then (
partRadius = value as number
)
else if volChild.name == "height" then (
partHeight = value as number
)
else if volChild.name == "dimensionX" then (
partDimX = value as number
)
else if volChild.name == "dimensionY" then (
partDimY = value as number
)
else if volChild.name == "dimensionZ" then (
partDimZ = value as number
)
)
) --if subPartEntry.name == "Volume"
) -- for partChildren.Count
-- Construct the bounds from the given info
pathList = filterstring partPath "|"
getobj = undefined
for i = 1 to pathList.count do (
if getobj == undefined then (
searchname = ""
searchname = RsSpaceToUnderscore(pathList[pathList.count - i + 1])
getobj = getnodebyname searchname exact:true
)
)
if getobj != undefined then (
idxCollType = getattrindex "Gta Collision" "Coll Type"
if partType == #box then (
newobj = Col_Box()
newobj.transform = partMat * getobj.transform
newobj.length = partDimX / 2.0
newobj.width = partDimY / 2.0
newobj.height = partDimZ / 2.0
newobj.parent = getobj
)
else if partType == #capsule then (
newobj = Col_Capsule()
newobj.transform = partMat * getobj.transform
newobj.length = partHeight
newobj.radius = partRadius
newobj.parent = getobj
)
setattr newobj idxCollType partName
)
) -- for rootChildren.Count
) --if nmRoot.name == "MODEL"
)
fn RsNmCreateRagdollBonerNode boneNode nmFilename = (
-- Get the node name
nodeName = RsLowercase boneNode.name
-- Check that this is a valid node
if classof boneNode != BoneGeometry then (
return 0
)
if findstring nodeName "footsteps" != undefined then (
return 0
)
-- Get the constraint filename
path = (filterString nmFilename "\\")
nmBaseFile = path[path.count]
conFilename = ( getdir #plugCfg ) + "constraints\\" + "constraint_" + nmBaseFile
-- Load the XML file
xmlDoc = XmlDocument()
xmlDoc.init()
xmlDoc.load conFilename
conRoot = xmlDoc.document.DocumentElement
-- Check that this is a valid XML
if conRoot.name == "MODEL" then (
currName = ""
rootChildren = conRoot.childnodes
-- Find the matching constraints for this node
for i = 0 to ( rootChildren.Count - 1 ) do (
partChild = rootChildren.itemof(i)
partChildren = partChild.childnodes
for i = 0 to ( partChildren.Count - 1 ) do (
-- Set the current child
currChild = partChildren.itemof(i)
-- Get the current name
if currChild.name == "name" then (
currName = RsRemoveFormatting currChild.innertext
)
-- If we found a match, set the constraints
if findstring nodeName currName != undefined then (
if currChild.name == "Constraint" then (
newCons = Constraint()
newCons.pickUpNode = boneNode
currChildren = currChild.childnodes
for i = 0 to ( currChildren.Count - 1 ) do (
conChild = currChildren.itemof(i)
value = (RsRemoveFormatting conChild.innertext) as integer
if conChild.name == "xmin" then ( newCons.xmin = value )
if conChild.name == "xmax" then ( newCons.xmax = value )
if conChild.name == "ymin" then ( newCons.ymin = value )
if conChild.name == "ymax" then ( newCons.ymax = value )
if conChild.name == "zmin" then ( newCons.zmin = value )
if conChild.name == "zmax" then ( newCons.zmax = value )
)
format "Created constraint for %\n" currName
return 0
) --if currChild.name == "Constraint"
) --if findstring nodeName currName != undefined
) --for partChildren.Count
) --for rootChildren.Count
) --if conRoot.name == "MODEL"
)
fn RsNmCreateRagdollSchemeRec rootNode nmFilename = (
RsNmCreateRagdollBonerNode rootNode nmFilename
for childNode in rootNode.children do (
RsNmCreateRagdollSchemeRec childNode nmFilename
)
)
fn RsNmCreateRagdollRemoveSchemeRec rootNode = (
if classof rootNode == Col_Capsule then (
delete rootNode
return 0
)
for childNode in rootNode.children do (
RsNmCreateRagdollRemoveSchemeRec childNode
)
)
-- Main function, loads all the NM information from the XML file
fn RsNmCreateRagdollScheme rootNode nmFilename = (
-- Load the bounds
print "RsNmCreateRagdollScheme"
RsNmLoadBound nmFilename
print "Bounds loaded"
-- Load the constraints
RsNmCreateRagdollSchemeRec rootNode nmFilename
print "Constraints loaded"
)