126 lines
4.1 KiB
Python
Executable File
126 lines
4.1 KiB
Python
Executable File
"""
|
|
Description:
|
|
Methods for manipulating and interacting with 3D Curves within motion builder
|
|
|
|
Authors:
|
|
David Vega <david.vega@rockstargames.com>
|
|
"""
|
|
|
|
import pyfbsdk
|
|
import RS.Utils.Creation
|
|
import RS.Utils.Math
|
|
from RS.Utils.Scene import Constraint
|
|
|
|
|
|
def CreatePath(*args, **kwargs):
|
|
return RS.Utils.Creation.CreatePath(*args, **kwargs)
|
|
|
|
|
|
def EditPath(*args, **kwargs):
|
|
return RS.Utils.Creation.EditPath(*args, **kwargs)
|
|
|
|
|
|
def SimplifyPath(path, samples=10, startRange=0, endRange=1):
|
|
if isinstance(path, basestring):
|
|
path = pyfbsdk.FBFindModelByLabelName(path)
|
|
|
|
return RS.Utils.Creation.CreatePath("Simple {}".format(path.Name), *[path.Total_GlobalPathEvaluate(
|
|
(((each/float(samples - 1)) * (endRange - startRange)) + startRange) * 100) for each in xrange(samples)])
|
|
|
|
|
|
def AttachComponentToPath(component, path, offset=[0,0,0], position=0):
|
|
constraint = Constraint.CreateConstraint(Constraint.PATH)
|
|
constraint.ReferenceAdd (0, component)
|
|
constraint.ReferenceAdd (1, path)
|
|
constraint.Snap()
|
|
constraint.PropertyList.Find("Translation Offset").Data = pyfbsdk.FBVector3d(*offset)
|
|
constraint.PropertyList.Find("Follow Path").Data = True
|
|
|
|
warp = constraint.PropertyList.Find("Warp")
|
|
warp.Data = position
|
|
warp.SetAnimated(True)
|
|
animationNode = warp.GetAnimationNode()
|
|
animationNode.FCurve.EditClear()
|
|
warp.SetAnimated(False)
|
|
return constraint
|
|
|
|
|
|
def GetPathConstraint(component, path=None):
|
|
constraints = [component.GetSrc(index)
|
|
for index in xrange(component.GetSrcCount())
|
|
if getattr(component.GetSrc(index), "Description", "") == "Path Constraint"]
|
|
|
|
if constraints:
|
|
return constraints[0]
|
|
|
|
elif not constraints and path:
|
|
return AttachComponentToPath(component, path)
|
|
|
|
|
|
def MapBoneChainLength(*bones, **kwargs):
|
|
children = kwargs.get("children", False)
|
|
if not bones: return
|
|
|
|
if children:
|
|
|
|
def getchildren(child):
|
|
children = [child]
|
|
for each in child.Children:
|
|
if isinstance(each, pyfbsdk.FBModelSkeleton):
|
|
children.extend(getchildren(each))
|
|
return children
|
|
|
|
bones = getchildren(bones[0])
|
|
|
|
length = 0
|
|
totalLengthProperties = []
|
|
|
|
for index, bone in enumerate(bones):
|
|
if index:
|
|
matrixA = pyfbsdk.FBMatrix()
|
|
bone.GetMatrix(matrixA)
|
|
|
|
matrixB = pyfbsdk.FBMatrix()
|
|
bones[index - 1].GetMatrix(matrixB)
|
|
|
|
matrix = matrixA - matrixB
|
|
lengthVector = [matrix[12], matrix[13], matrix[14]]
|
|
length += RS.Utils.Math.Length(*lengthVector)
|
|
|
|
for propertyName in ["ChainLength", "TotalLength"]:
|
|
property = bone.PropertyList.Find(propertyName)
|
|
if not property:
|
|
property = bone.PropertyCreate(propertyName, pyfbsdk.FBPropertyType.kFBPT_double, 'Double',
|
|
True, True, None)
|
|
if property == "TotalLength":
|
|
totalLengthProperties.append(property)
|
|
property.Data = length
|
|
|
|
[setattr(each, "Data", length) for each in totalLengthProperties]
|
|
|
|
|
|
def KeepBoneEqualDistance(path, *joints, **kwargs):
|
|
frame = kwargs.get("Frame", pyfbsdk.FBSystem().LocalTime.GetFrame())
|
|
for joint in joints:
|
|
constraint = GetPathConstraint(joint, path)
|
|
length = joint.PropertyList.Find("ChainLength").Data * 100
|
|
position = length/float(path.PathLength)
|
|
warp = constraint.PropertyList.Find("Warp")
|
|
warp.Data = position
|
|
#warp.SetAnimated(True)
|
|
#animationNode = warp.GetAnimationNode()
|
|
#animationNode.FCurve.EditClear()
|
|
#warp.SetAnimated(False)
|
|
#animationNode.KeyAdd(
|
|
# pyfbsdk.FBTime(0, 0, 0, frame), position)
|
|
|
|
|
|
|
|
"""
|
|
import RS.Utils.Math as p
|
|
reload(p)
|
|
import RS.Utils.Path3D as p
|
|
reload(p)
|
|
p.MapBoneChainLength(FBFindModelByLabelName("Skeleton node"))
|
|
p.KeepBoneEqualDistance(FBFindModelByLabelName("3D Curve"), *var)
|
|
""" |