172 lines
5.9 KiB
Plaintext
Executable File
172 lines
5.9 KiB
Plaintext
Executable File
|
|
struct SkinnedObject_Bone_VertexWeight ( VertID, Weight )
|
|
struct SkinnedObject_Bone
|
|
(
|
|
--Node = Point AxisTripod:True Cross:False Size:1.0 WireColor:Blue ,
|
|
Node = Dummy(),
|
|
VertexWeightTable = #(),
|
|
|
|
--This just stores the references to any children nodes. Mainly used for keeping track of particle helpers and lights etc..
|
|
ChildNodeArray = #(),
|
|
|
|
--Clones and return This. VertexIDs are offset by passed VertexIDOffset value.
|
|
fn Clone VertIDOffset:0 =
|
|
(
|
|
ClonedBone = SkinnedObject_Bone()
|
|
ClonedBone.CreateFromNode This.Node
|
|
ClonedBone.CopyVertexWeightTable This.VertexWeightTable VertIDOffset:VertIDOffset
|
|
ClonedBone.ChildNodeArray = This.ChildNodeArray
|
|
|
|
--Return the new cloned bone
|
|
Return ClonedBone
|
|
),
|
|
|
|
/*--------------------------------------------------
|
|
Sets up this bone to mirror the animation of the passed node
|
|
*/---------------------------------------------------
|
|
fn CreateFromNode InputNode =
|
|
(
|
|
--Logic for making dummys match the bounds of the passed object. Doesn't work that well atm
|
|
NodeBoundingBox = NodeGetBoundingBox InputNode InputNode.Transform
|
|
NodeBoundingBox = NodeBoundingBox[2] - NodeBoundingBox[1]
|
|
This.Node.Boxsize = [NodeBoundingBox.x, NodeBoundingBox.y, NodeBoundingBox.z]
|
|
|
|
--This.Node.ObjectOffsetPos = (InputNode.Center - This.Node.Pivot)
|
|
--This.Node.Pivot = InputNode.Center
|
|
|
|
for Child in InputNode.Children do
|
|
(
|
|
Append ChildNodeArray Child
|
|
)
|
|
|
|
--First we must move the bone node to the input nodes position so that auto key doesn't create a really weird interpolation to the origin if the animation time frame doesn't start at zero.
|
|
This.Node.Transform = InputNode.Transform
|
|
|
|
--Get the timespan of the max scene
|
|
StartFrame = AnimationRange.Start.Frame as integer
|
|
EndFrame = AnimationRange.End.Frame as integer
|
|
|
|
--For each frame key the bone node against the input node
|
|
for CurrentFrame = StartFrame to EndFrame do
|
|
(
|
|
animate on, at time CurrentFrame
|
|
(
|
|
This.Node.Transform = InputNode.Transform
|
|
)
|
|
)
|
|
|
|
--Copy other required tracks across
|
|
--[R.G] Removing this for now
|
|
--RSCopyTrack InputNode This.Node "Visibility"
|
|
|
|
|
|
--Clean up the keys. Not needed for time being.
|
|
--ReduceKeys This.Node.Transform.Controller 0.5 1f
|
|
),
|
|
|
|
|
|
/*--------------------------------------------------
|
|
Copies the passed vertex weight table into this bone instance. If passed the VertIDOffset will offset the VertIDs
|
|
*/---------------------------------------------------
|
|
fn CopyVertexWeightTable InputVertexWeightTable VertIDOffset:0 =
|
|
(
|
|
This.VertexWeightTable = #()
|
|
|
|
for VertexWeight in InputVertexWeightTable do
|
|
(
|
|
CopiedVertexWeight = SkinnedObject_Bone_VertexWeight()
|
|
CopiedVertexWeight.VertID = VertexWeight.VertID + VertIDOffset
|
|
CopiedVertexWeight.Weight = VertexWeight.Weight
|
|
Append This.VertexWeightTable CopiedVertexWeight
|
|
)
|
|
),
|
|
|
|
/*--------------------------------------------------
|
|
Processes the weights from the passed table creating a vertex weight table. All weights that are 0.0 are ignored to save heap memory. The distinction between a vertex weight table and a normal weight table is that the vertex weight table stores the VertID rather than it being implicit by the position (within the array) of the value in a normal weight table.
|
|
*/---------------------------------------------------
|
|
fn MapWeightTable InputWeightTable =
|
|
(
|
|
This.VertexWeightTable = #()
|
|
|
|
VertID = 1
|
|
for Weight in InputWeightTable do
|
|
(
|
|
--If the weight is greater than 0.0 then add it, else we don't bother. Saves on heap memory
|
|
if( Weight > 0 ) then
|
|
(
|
|
Append This.VertexWeightTable (SkinnedObject_Bone_VertexWeight VertID:VertID Weight:Weight)
|
|
)
|
|
VertID += 1
|
|
)
|
|
),
|
|
|
|
/*--------------------------------------------------
|
|
Reorganises the weights of the bone so that they are order correctly
|
|
*/---------------------------------------------------
|
|
fn CondenseWeights =
|
|
(
|
|
--First we reorder all the weights by VertID
|
|
fn SortFunction LeftVertexWeight RightVertexWeight =
|
|
(
|
|
if( LeftVertexWeight.VertID < RightVertexWeight.VertID ) then return -1
|
|
if( LeftVertexWeight.VertID == RightVertexWeight.VertID ) then return 0
|
|
if( LeftVertexWeight.VertID > RightVertexWeight.VertID ) then return 1
|
|
)
|
|
QSort VertexWeightTable SortFunction
|
|
|
|
--Then set the VertID to ascend linearlly 1..2...
|
|
for i = 1 to VertexWeightTable.Count do
|
|
(
|
|
VertexWeightTable[i].VertID = i
|
|
)
|
|
),
|
|
|
|
/*--------------------------------------------------
|
|
Returns all the verts that this bone affects
|
|
*/---------------------------------------------------
|
|
fn GetVertIDArray =
|
|
(
|
|
return (for VertexWeight in This.VertexWeightTable collect VertexWeight.VertID)
|
|
),
|
|
|
|
|
|
/*---------------------------------------------------
|
|
Reorders the VertexWeights of the bones with the passed remap table
|
|
*/---------------------------------------------------
|
|
fn ReorderVertIDs VertIDRemapTable =
|
|
(
|
|
for VertexWeight in VertexWeightTable do
|
|
(
|
|
VertexWeight.VertID = VertIDRemapTable.GetNewVertID( VertexWeight.VertID )
|
|
)
|
|
),
|
|
|
|
/*--------------------------------------------------
|
|
Checks if this bone has any VertexWeights that affect any matching verts in the passed array
|
|
*/---------------------------------------------------
|
|
fn HasConflictingWeights InputVertIDArray =
|
|
(
|
|
for VertexWeight in This.VertexWeightTable do
|
|
(
|
|
if ( FindItem InputVertIDArray VertexWeight.VertID ) != 0 then
|
|
(
|
|
return True --A conflict has been found
|
|
)
|
|
)
|
|
|
|
return False --No conflict was found
|
|
),
|
|
|
|
/*---------------------------------------------------
|
|
Destroys everything related to this bone ready for GC
|
|
*/---------------------------------------------------
|
|
fn Destroy =
|
|
(
|
|
Delete This.Node
|
|
This.ChildNodeArray = #()
|
|
This.VertexWeightTable = #()
|
|
)
|
|
)
|
|
|
|
|