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

257 lines
8.2 KiB
Plaintext
Executable File

fn HasSkinning Obj =
(
for SubModifier in Obj.Modifiers do
(
if ClassOf SubModifier == Skin then
(
return True
)
)
return False
)
/*---------------------------------------------------
Struct that allow us to interact with a skin modifer in a more intuitive way
*/---------------------------------------------------
struct SkinModifier
(
TargetModifier = Undefined,
TargetNode = Undefined,
/*---------------------------------------------------
Returns the first Skin modifier on the passed objects stack. Returns Undefined if there isn't one.
*/---------------------------------------------------
fn ExtractSkinModifier InputGeometryNode =
(
This.TargetNode = InputGeometryNode
This.TargetModifier = Undefined
for SubModifier in This.TargetNode.Modifiers do
(
if ClassOf SubModifier == Skin then
(
This.TargetModifier = SubModifier
return True
)
)
return False
),
/*---------------------------------------------------
Returns the first Skin modifier on the passed objects stack. Returns Undefined if there isn't one.
*/---------------------------------------------------
fn SetupSkinModifier InputGeometryNode =
(
This.TargetNode = InputGeometryNode
This.TargetModifier = Skin()
AddModifier This.TargetNode This.TargetModifier
),
/*---------------------------------------------------
Updates the SkinModifier. Needed occasionally to prompt max before more operations are performed.
*/---------------------------------------------------
fn ForceUpdate =
(
--Extract the skin data. Seems to give the modifier a refresh.
SkinUtils.ExtractSkinData This.TargetNode
--Delete the mesh that gets created from the above operation. Should be the last created node.
Delete( Objects[Objects.Count] )
),
/*---------------------------------------------------
Removes any weight values of 0.0
*/---------------------------------------------------
-- fn RemoveZeroWeights =
-- (
--
-- ),
/*---------------------------------------------------
Returns the actual node that corrolates to the BoneID past as input
*/---------------------------------------------------
fn GetBoneNode BoneID =
(
--Because the Skin modififer will only pass back a string name we have to give every node that relates to the Skin modifer a unique handle so we can be sure we are obtaining the correct node. We reverse this operation at the end of the function so that we leave the scene as it was. Should be relatively quick.
--Collect all of the Node based dependencies for this SkinModifier
NodeDependencies = for Dependant in (Refs.DependsOn This.TargetModifier) where IsValidNode Dependant collect #(Dependant, Dependant.Name)
--Rename each dependant to it's unique handle so we can interact with it safely
for SubNode in NodeDependencies do
(
SubNode[1].Name = SubNode[1].Handle as String
)
--Now get the bone by name. We should only get one.
BoneName = SkinOps.GetBoneName TargetModifier BoneID 0
BoneNode = ( for SubNode in NodeDependencies where SubNode[1].Name == BoneName collect SubNode[1] )[1]
--Reverse the renaming operation
for SubNode in NodeDependencies do
(
SubNode[1].Name = SubNode[2]
)
--Return our bone node
return BoneNode
),
/*---------------------------------------------------
Returns the number of bones in the skin modifier
*/---------------------------------------------------
fn BoneCount =
(
SkinOps.GetNumberBones TargetModifier
),
/*---------------------------------------------------
Gets the weight table for the passed BoneID
*/---------------------------------------------------
fn GetWeightTable BoneID =
(
ReturnWeightTable = #()
for VertID = 1 to SkinOps.GetNumberVertices This.TargetModifier do
(
--Get the current weight
CurrentWeightValue = This.GetVertexWeight VertID BoneID
Append ReturnWeightTable CurrentWeightValue
)
return ReturnWeightTable
),
/*---------------------------------------------------
Gets the weight for the past VertID and and BoneID
*/---------------------------------------------------
fn GetVertexWeight VertID BoneID =
(
for BoneVertID = 1 to SkinOps.GetVertexWeightCount This.TargetModifier VertID do
(
CurrentBoneID = SkinOps.GetVertexWeightBoneID This.TargetModifier VertID BoneVertID
if CurrentBoneID == BoneID then
(
return SkinOps.GetVertexWeight This.TargetModifier VertID BoneVertID
)
)
return 0.0
),
/*---------------------------------------------------
Deletes the passed BoneID
*/---------------------------------------------------
fn AddBone BoneNode =
(
SkinOps.AddBone This.TargetModifier BoneNode 1
),
/*---------------------------------------------------
Adds the passed node as a bone
*/---------------------------------------------------
fn RemoveBone BoneID =
(
SkinOps.RemoveBone This.TargetModifier BoneID
),
/*---------------------------------------------------
Sets the weight for the past VertID and and BoneID
*/---------------------------------------------------
fn SetVertexWeight VertID BoneID Weight =
(
SkinOps.SetVertexWeights This.TargetModifier VertID BoneID Weight
),
/*---------------------------------------------------
Sets the weight for all the verts on the BoneID to the passed weight value.
*/---------------------------------------------------
fn ResetBoneWeights BoneID Weight =
(
for VertID = 1 to SkinOps.GetNumberVertices This.TargetModifier do
(
SetVertexWeight VertID BoneID Weight
)
--GC()
),
/*---------------------------------------------------
Sets the weight for all the verts on all bones to the passed weight value. Useful for reseting all values before pushing new values to a bone.
*/---------------------------------------------------
fn ResetAllBoneWeights Weight =
(
BoneArray = #{1..BoneCount()} as Array
WeightArray = for Value in BoneArray collect Weight
for VertID = 1 to SkinOps.GetNumberVertices This.TargetModifier do
(
SkinOps.SetVertexWeights This.TargetModifier VertID BoneArray WeightArray
)
),
/*---------------------------------------------------
Resets the bone to use it's default values
*/---------------------------------------------------
fn ResetBone BoneID =
(
SkinOps.SelectBone This.TargetModifier BoneID
SkinOps.ResetSelectedBone This.TargetModifier
),
/*---------------------------------------------------
Unnormalize all the verts. Allows us to push whatever values we want onto them
*/---------------------------------------------------
fn UnNormalizeVerts State =
(
--Before we do this we must check to ensure that we have at least one bone. If we don't then this operation will do nothing. By adding a temporary bone performing the operation and then removing it we make the changes hold.
TempBoneNode = undefined
if This.BoneCount() == 0 then
(
--Create the temporary bone add it.
TempBoneNode = Dummy Name:"__TEMP__"
This.AddBone TempBoneNode
This.ForceUpdate()
)
--Go through each vert and 'UnNormalize' it.
for VertID = 1 to SkinOps.GetNumberVertices This.TargetModifier do
(
SkinOps.UnNormalizeVertex This.TargetModifier VertID State
)
--Delete the temporary bone if it exists. By deleting the node the bone is automatically removed from the skin.
if IsValidNode TempBoneNode then Delete TempBoneNode
),
fn GetAffectVertCount BoneID =
(
),
/*---------------------------------------------------
These functions and variables track whether the object is in a state which can be minipulated without max crashing. These must be called before doing certain operations on the SkinModifier.
*/---------------------------------------------------
Editable = False,
fn StartEdit =
(
if not Editable then
(
Select TargetNode
SetCommandPanelTaskMode Mode:#Modify
ModPanel.SetCurrentObject This.TargetModifier
if SkinOps.IsWeightToolOpen This.TargetModifier == 1 then
(
SkinOps.CloseWeightTool This.TargetModifier
)
)
),
fn EndEdit =
(
Editable = False
)
)