Object Hierarchy | 関連する C++クラス:ShapeClip
ShapeClip
v1.5
ShapeClip
オブジェクトは、アニメーションミキサのシェイプトラックのある特定位置における、シェイプキー(ソース)のインスタンスです。Geometry.SaveShapeKeyメソッドを使用してシェイプクリップを作成できます。既存のシェイプクリップを列挙するには、シェイプトラックの
ClipList のフルパスを、ShapeClip オブジェクトを戻すEnumElementsコマンドに渡す必要があります。
AddClipコマンドを使用して、同じソースを持つ複数クリップを作成できます。これは、同一アニメーション内で同一オブジェクトに複数回戻したり、トラック上のシェイプクリップの順序を並べ替えてシェイプアニメーションを完全に変更したりすることにより可能となります。
ShapeClip オブジェクトでClip.MappedItemsメソッド使用し、クラスタに格納されているシェイプアニメーションにアクセスできます。各MappedItemオブジェクトは、MappedItem.Source2メソッドからShapeKeyオブジェクト(ClusterPropertyの特殊な種類)を返します。ShapeKeyにはシェイプアニメーションデータが含まれます。ShapeKey
のベースプロパティSIObject.Parentを使用して、シェイプアニメーションされたClusterオブジェクトを取得できます。
ローカルリファレンスモード(siShapeLocalReferenceMode)でシェイプキーを保存すると、ポイントのローカルリファレンスに対するデルタ(差分)のみが保存されます。シェイプ内の各ポイントの絶対座標を取得する必要がある場合は、シェイプキーを適用する前に、ポイントのローカルリファレンスおよびそのポイントの元の座標を取得する必要があります。
ローカルリファレンス(Geometry0D.LocalReferenceFrame)および各ポイントの元の座標を取得する場合は、DeactivateAboveコマンドを使用して、シェイプコンバイナーおよびその上にある他のすべてのオペレータをミュートする必要があります。
'
' The following example illustrates how to access the position
' information stored in a shape key. Adding a shape key using
' local reference mode will store the positions as deltas to
' the local referential of each point. To calculate the
' absolute position for each point you need the local
' referential for the point and the original position before
' the shape was applied.
'
' Create the scene with an object with a shape clip
NewScene , false
set root = ActiveSceneRoot
set c1 = root.AddGeometry( "Cube", "MeshSurface" )
set c2 = Duplicate( c1, , 2, 1, 1, 0, 0, 1, 0, 1 )(0)
Translate c2, 10, 0, -2, siRelative, siView, siObj, siXYZ
Translate c2 & ".pnt[2,3,6,LAST]", -6, -4, 4, siRelative, siView, siObj, siXYZ
' Add a shapeclip where the position data is stored as deltas to
' the point's local referential. You can also store the shape in
' absolute mode in which case the cluster property contains
' for the shape the actual point data or you can store it in
' object mode in which case deltas are stored in the object
' referential (i.e. the pose of the object).
set key = SelectShapeKey( c1, c2, siShapeLocalReferenceMode )
dim mix
if root.HasMixer() then
set mix = root.Mixer
else
set mix = root.AddMixer()
end if
set shapetrack = AddTrack( root, mix, 1 )
AddClip root, key, , shapetrack, 1, , , , False
'
' Get the shapeclip
'
dim clip
for each c in mix.Clips
if c.Type = siClipShapeType then
set clip = c
end if
next
' We need to mute the shape combiner and all the operators above it
' inorder to get the local reference frame and position of each
' point before the shape animation was applied to the geometry.
' (This gives the position values before the shape that was stored
' and does not include the result of deformations applied afterwards.)
set geom = Nothing
set oMatrix33 = XSIMath.CreateMatrix3
set oDelta = XSIMath.CreateVector3
set oXAxis = XSIMath.CreateVector3
set oYAxis = XSIMath.CreateVector3
set oZAxis = XSIMath.CreateVector3
for idx=0 to clip.MappedItems.Count-1
set mi = clip.MappedItems(idx)
LogMessage TypeName(mi)
LogMessage TypeName(mi.Source2)
' Get the cluster property/shape key stored in the shapeclip
set clsprop = mi.Source2
' Since the geometry for each mappeditem will be
' the same we'll only need to get it once.
if TypeName(geom) = "Nothing" then
' Get the cluster, primitive and geometry from the
' cluster property
set cls = clsprop.Parent
set geom = cls.Parent
set prim = geom.Parent
' Deactivate all operators above and including the shape combiner
DeactivateAbove prim.FullName & ".clustershapecombiner", True
' Get the position array from the geometry
aPosition = geom.Points.PositionArray
' Get the old Geometry0D object to access
' the local reference frame for each point
set geomv1 = geom.Parent.Obj
set o0DGeometry = geomv1.Geometry0D
end if
' Assume that the number of cluster property elements
' matches the geometry and that they are same order i.e.
' point0 == clusterelement0
' Get the delta position array from the clusterproperty
aDelta = clsprop.Elements.Array
' Figure out the absolute position value using the deltas,
' the original point position and the local referential
' of each point
for i=LBound( aDelta, 2 ) to UBound( aDelta, 2 )
' Set a vector3 with the delta for the position
oDelta.Set aDelta( 0, i ), aDelta( 1, i ), aDelta( 2, i )
' Get the local reference frame for the point
o0DGeometry.LocalReferenceFrame i, _
oXAxis, oXAxisValid, _
oYAxis, oYAxisValid, _
oZAxis, oZAxisValid
' Get the transformation matrix to go from point
' local reference frame to object referential
oMatrix33.Set _
oXAxis.X , oXAxis.Y, oXAxis.Z, _
oYAxis.X , oYAxis.Y, oYAxis.Z, _
oZAxis.X , oZAxis.Y, oZAxis.Z
oDelta.MulByMatrix3 oDelta, oMatrix33
' Set a vector3 with the point position
set oPosition = XSIMath.CreateVector3
oPosition.Set _
aPosition( 0, i ), _
aPosition( 1, i ), _
aPosition( 2, i )
' Compute the absolute position by adding the delta
oPosition.AddInPlace oDelta
' Log the absolute position values for the point
LogMessage oPosition.X & "," & oPosition.Y & "," & oPosition.Z
next
next
' Reactivate shapecombiner and all operators above it
if TypeName(prim) <> "Nothing" then
DeactivateAbove prim.FullName & ".clustershapecombiner", False
end if
' Enumerate the shapeclips under the mixer shape track.
for each t in ActiveSceneRoot.Mixer.Tracks
if t.Type = siTrackShapeType then
set shapetrack = t
exit for
end if
next
for each shapeclip in shapetrack.Clips
LogMessage shapeclip
next
'Expected results:
'INFO : MappedItem
'INFO : ShapeKey
'INFO : -4,-4,-4
'INFO : 4,-4,-4
'INFO : -10,1.33226762955019E-15,-1.33226762955019E-15
'INFO : -2,1.33226762955019E-15,-1.33226762955019E-15
'INFO : -4,-4,4
'INFO : 4,-4,4
'INFO : -10,8.88178419700125E-16,8
'INFO : -2,8.88178419700125E-16,8
'INFO : Mixer.Mixer_Shape_Track.cube1_ShapeKey_Clip
|
/*
This Shape Animation example demonstrates how to use GetDrivingActions()
to get at the ShapeClips which animate an object. It also demonstrates
how to access the fcurves on each clip
*/
// Create a little sample scene with a simple animated sphere
NewScene( null, false );
// Make sure we are in Mixed Weight Mode
SetUserPref( "ShapeInstancingMode", 1 );
var oSphere = ActiveSceneRoot.AddGeometry( "Sphere", "MeshSurface" );
SaveShapeKey( "sphere", null, null, 1, null, null, null, null,
siShapeLocalReferenceMode );
// Move a vertice and record that as the shape at frame 20
SelectGeometryComponents( "sphere.pnt[33]" );
Translate( null, 3, 0, 0, siRelative, siView, siObj, siXYZ );
SaveShapeKey( oSphere + ".pnt[33]", null, null, 20, null, null, null, null,
siShapeLocalReferenceMode );
// Move another point as shape for frame 30
SelectGeometryComponents( "sphere.pnt[1]" );
Translate( null, 0, 3, 0, siRelative, siView, siObj, siXYZ );
SaveShapeKey( oSphere + ".pnt[1]", null, null, 30, null, null, null, null,
siShapeLocalReferenceMode );
// Access the ShapeClips which have been created on the object
var oClips = GetDrivingActions( oSphere, false, null, false, false );
for ( var i=0; i<oClips.Count; i++ ) {
// Get the clip
var oClip = oClips(i);
// Access the animated parameter which controls the weight of the clip
// in the mixer
var oParam = Dictionary.GetObject( oClip + ".actionclip.weight" );
var oFCurve = oParam.Source;
// At frame 40 we will do an equal blend of all the shapes
oFCurve.AddKey( 40, 1 );
// Print out the keys
var oFCurveKeys = oFCurve.Keys;
LogMessage( "FCurve on " + oClip );
for ( var j=0; j<oFCurveKeys.Count; j++ ) {
var oFCurveKey = oFCurveKeys.Item( i );
LogMessage( " Time:" + oFCurveKey.Time + "-" + oFCurveKey.Value );
}
}
// Expected result:
//INFO : FCurve on Mixer.Mixer_Shape_Track.Shape_ClusterClip.Mixer_Shape_Track3.ShapeKey2_Clip
//INFO : Time:20-0
//INFO : Time:20-0
//INFO : Time:20-0
//INFO : FCurve on Mixer.Mixer_Shape_Track.Shape_ClusterClip.Mixer_Shape_Track2.ShapeKey1_Clip
//INFO : Time:20-1
//INFO : Time:20-1
//INFO : Time:20-1
//INFO : Time:20-1
//INFO : FCurve on Mixer.Mixer_Shape_Track.Shape_ClusterClip.Mixer_Shape_Track1.ShapeKey_Clip
//INFO : Time:40-1
//INFO : Time:40-1
//INFO : Time:40-1
|