313 lines
8.8 KiB
Plaintext
Executable File
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"
|
|
) |