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 |