127 lines
2.9 KiB
Plaintext
Executable File
127 lines
2.9 KiB
Plaintext
Executable File
--This script will remove dead (unused) sections of a bone hierarchy from a skin.
|
|
--It will not remove a bone if any decendants of the bone is in use.
|
|
|
|
idxIsClothCollision = ( GetAttrIndex "Gta Collision" "Is Cloth Collision" )
|
|
|
|
fn findRemoveBoneList obj =
|
|
(
|
|
skinMod = obj.modifiers[#Skin]
|
|
select obj
|
|
max modify mode
|
|
totalBones = skinOps.getNumberBones skinMod
|
|
|
|
boneNameRemovalList = #()
|
|
for boneID = 1 to totalBones do
|
|
(
|
|
if ( boneIsNotUsed obj boneID skinMod ) then
|
|
(
|
|
boneName = skinOps.GetBoneName skinMod boneID 1
|
|
appendIfUnique boneNameRemovalList boneName
|
|
)
|
|
)
|
|
|
|
for boneName in boneNameRemovalList do
|
|
(
|
|
boneNode = GetNodeByName boneName
|
|
if not ( IsValidNode thisBoneNode ) then continue
|
|
|
|
if( allDecendentsAreMarkedForRemoval ) then
|
|
(
|
|
print ("Removing "+boneName+" from "+obj.name)
|
|
|
|
matchingBoneID = -1
|
|
for queryBoneID = 1 to totalBones do
|
|
(
|
|
queryBoneName = skinOps.GetBoneName skinMod queryBoneID 1
|
|
if( queryBoneName == boneName ) then
|
|
(
|
|
matchingBoneID = queryBoneID
|
|
exit
|
|
)
|
|
)
|
|
|
|
if( matchingBoneID != -1 ) then
|
|
(
|
|
skinOps.SelectBone skinMod matchingBoneID
|
|
skinOps.removebone skinMod
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
fn allDecendentsAreMarkedForRemoval obj matchNameArray =
|
|
(
|
|
for child in obj.children do
|
|
(
|
|
if not( contains matchNameArray child.name ) then
|
|
(
|
|
return False
|
|
)
|
|
|
|
if not( allDecendentsAreMarkedForRemoval child matchNameArray ) then
|
|
(
|
|
return False
|
|
)
|
|
)
|
|
|
|
return True
|
|
)
|
|
|
|
fn boneIsNotUsed obj boneID skinMod =
|
|
(
|
|
thisBoneName = skinOps.GetBoneName skinMod boneID 1
|
|
thisBoneNode = GetNodeByName thisBoneName
|
|
|
|
--Check to see if the bone has cloth collision added to it
|
|
if( IsValidNode thisBoneNode ) then
|
|
(
|
|
for child in thisBoneNode.children do
|
|
(
|
|
if( GetAttrClass child == "Gta Collision" ) then
|
|
(
|
|
if( GetAttr child idxIsClothCollision ) then
|
|
(
|
|
return False
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
totalVerts = skinOps.getNumberVertices skinMod
|
|
for v = 1 to totalVerts do --now we test each vert and see if this bones is weighted to it
|
|
(
|
|
weightCount = skinOps.GetVertexWeightCount skinMod v --first get the no of influences on this vert
|
|
|
|
for vB = 1 to weightCount do
|
|
(
|
|
tB = skinOps.getVertexWeightBoneID skinMod v vB
|
|
|
|
if tB == boneID do --this means we have found the match to the skinModBones bones we are on
|
|
(
|
|
vtWeight = skinOps.getVertexWeight skinMod v vB
|
|
|
|
if vtWeight != undefined do
|
|
(
|
|
if vtWeight >= 0.0 do
|
|
(
|
|
return False
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
return True
|
|
)
|
|
|
|
selA = selection as array
|
|
|
|
for a = 1 to sela.count do
|
|
(
|
|
if sela[a].modifiers[#Skin] != undefined do
|
|
(
|
|
try (findRemoveBoneList sela[a]) catch (Print (sela[a].name+" has a prob!"))
|
|
)
|
|
-- messagebox ("Removal COMPLETE!") beep:true
|
|
)
|
|
messagebox ("Removal COMPLETE!") beep:true |