An envelope is an object or hierarchy that is assigned as a skin to a set of deformers such as IK chains. Envelopes move and deform in response to the movement of their deformers. In this way, for example, a character moves as you animate its skeleton.
Every point in an envelope is assigned to one or more deformers. Weights determine the relative influence of a deformer on a given point of the envelope.
Although it is common to use skeletons as deformers, you can actually use any object. The geometry of a deformer does not matter because the points of the envelope are assigned to its center. Bones are the exception; in this case, points are deformed by the whole length of the bone).
#include <xsi_envelope.h>
Public Member Functions | |
Envelope () | |
~Envelope () | |
Envelope (const CRef &in_ref) | |
Envelope (const Envelope &in_obj) | |
bool | IsA (siClassID in_ClassID) const |
siClassID | GetClassID () const |
Envelope & | operator= (const Envelope &in_obj) |
Envelope & | operator= (const CRef &in_ref) |
CRefArray | GetDeformers () const |
CClusterPropertyElementArray | GetWeights (double in_dFrame) const |
CClusterElementArray | GetElements (double in_dFrame) const |
CDoubleArray | GetDeformerWeights (const X3DObject &in_Deformer, double in_dFrame) const |
CStatus | SetDeformerWeights (X3DObject &in_Deformer, const CDoubleArray &in_Array) |
CStatus | GetDeformerColor (const X3DObject &in_Deformer, CColor &io_Color) const |
CStatus | SetDeformerColor (const X3DObject &in_Deformer, const CColor &in_Color) |
CStatus | SetDeformerWeights2 (X3DObject &in_Deformer, const CDoubleArray &in_Array) |
Envelope | ( | ) |
Default constructor.
~Envelope | ( | ) |
Default destructor.
bool IsA | ( | siClassID | in_ClassID | ) | const [virtual] |
Returns true if a given class type is compatible with this API class.
in_ClassID | class type. |
Reimplemented from Operator.
siClassID GetClassID | ( | ) | const [virtual] |
Creates an object from another object. The newly created object is set to empty if the input object is not compatible.
in_obj | constant class object. |
CRefArray GetDeformers | ( | ) | const |
Returns an array of references to the deformer objects of this envelope.
myEnvelope.GetDeformerWeights( X3DObject( myCRefArray[someIndex] ) );
CClusterPropertyElementArray GetWeights | ( | double | in_dFrame | ) | const |
Returns the weights for every deformer at a given frame.
________________________________________________ | Index 0 | Index 1 || Index 2 | Index 3 | |-----------+-----------++-----------+-----------| | Cluster element 0 || Cluster element 1 | |===========+===========++===========+===========| | Weight of | Weight of || Weight of | Weight of | |deformer 0 |deformer 1 ||deformer 0 |deformer 1 | ------------------------------------------------
in_dFrame | Frame at which to get the deformers |
using namespace XSI; Application app; Model root = app.GetActiveSceneRoot(); Null myDeformer1; root.AddNull( L"", myDeformer1 ); Null myDeformer2; root.AddNull( L"", myDeformer2 ); KinematicState nullGlobalKineState(myDeformer1.GetKinematics().GetGlobal()); Parameter param(nullGlobalKineState.GetParameters().GetItem(L"posx")); param.PutValue( (double)4.0 ); param = nullGlobalKineState.GetParameters().GetItem(L"posy"); param.PutValue( (double)3.0 ); X3DObject mySphere; root.AddGeometry( L"Sphere", L"MeshSurface", L"", mySphere ); param = mySphere.GetKinematics().GetGlobal().GetParameters().GetItem(L"posz"); param.PutValue( (double)2.0 ); CRefArray deformers(2); deformers[0] = myDeformer1; deformers[1] = myDeformer2; Envelope myEnvelope; mySphere.ApplyEnvelope( deformers, siUnspecified, siUnspecified, myEnvelope ); // get the weights at the current frame CTime time; CClusterPropertyElementArray weights = myEnvelope.GetWeights( time.GetTime() ); CDoubleArray weightArray = weights.GetArray(); wchar_t msg[30]; LONG weightArrayCount = weightArray.GetCount(); LONG deformerCount = weights.GetValueSize(); // for each cluster element in the envelope for ( register LONG i = 0L; i < weightArrayCount; i += deformerCount ) { swprintf( msg, L"Element #%d weights:", i / deformerCount ); CString csMsg( msg ); // for each deformer of the current cluster element for ( register LONG j = 0L; j < deformerCount; j++ ) { // show weight for current deformer swprintf( msg, L"\n\t\tDeformer #%d = %f", j, weightArray[i + j] ); csMsg += msg; } app.LogMessage( csMsg ); }
CClusterElementArray GetElements | ( | double | in_dFrame | ) | const |
Returns the cluster elements composing this envelope at a given frame.
in_dFrame | Frame at which to get the cluster elements. |
CDoubleArray GetDeformerWeights | ( | const X3DObject & | in_Deformer, |
double | in_dFrame | ||
) | const |
Returns the weights of a specific deformer at a given frame.
in_Deformer | The deformer to get |
in_dFrame | Frame at which to get the deformer |
CStatus SetDeformerWeights | ( | X3DObject & | in_Deformer, |
const CDoubleArray & | in_Array | ||
) |
Sets the weights of the specified deformer and normalizes the weights.
in_Deformer | The deformer to set |
in_Array | Array of weight values to apply |
using namespace XSI; Application app; Model root = app.GetActiveSceneRoot(); Null myDeformer1; root.AddNull( L"", myDeformer1 ); Null myDeformer2; root.AddNull( L"", myDeformer2 ); KinematicState nullGlobalKineState(myDeformer1.GetKinematics().GetGlobal()); Parameter param(nullGlobalKineState.GetParameters().GetItem(L"posx")); param.PutValue( (double)4.0 ); param = nullGlobalKineState.GetParameters().GetItem(L"posy"); param.PutValue( (double)3.0 ); X3DObject mySphere; root.AddGeometry( L"Sphere", L"MeshSurface", L"", mySphere ); param = mySphere.GetKinematics().GetGlobal().GetParameters().GetItem(L"posz"); param.PutValue( (double)2.0 ); CRefArray deformers(2); deformers[0] = myDeformer1; deformers[1] = myDeformer2; Envelope myEnvelope; mySphere.ApplyEnvelope( deformers, siUnspecified, siUnspecified, myEnvelope ); // get the first deformer X3DObject firstDeformer( myEnvelope.GetDeformers()[0] ); // Get its weights at frame 0 CDoubleArray weights = myEnvelope.GetDeformerWeights( firstDeformer, 0.0 ); // Set the weights to 75 for the current frame LONG weightCount = weights.GetCount(); register LONG i = 0L; for ( ; i < weightCount; i++ ) weights[i] = 75.0; myEnvelope.SetDeformerWeights( firstDeformer, weights ); wchar_t msg[128]; CRefArray myDeformers = myEnvelope.GetDeformers(); LONG deformerCount = myDeformers.GetCount(); CTime frame; // for each deformer for ( i = 0L; i < deformerCount; i ++ ) { swprintf( msg, L"Deformer #%d:", i ); app.LogMessage( msg ); // display the weights for the envelope at the current frame weights = myEnvelope.GetDeformerWeights( X3DObject(myDeformers[i]), frame.GetTime() ); LONG elementCount = weights.GetCount(); for ( register LONG i = 0L; i < elementCount; i++ ) { swprintf( msg, L"Element %d = %f", i, weights[i] ); app.LogMessage( msg ); } }
Returns the color of the specified deformer.
in_Deformer | The deformer to get |
io_Color | Color of the deformer (as a CColor) |
Sets the color of a given deformer.
in_Deformer | The deformer to set |
in_Color | New color of the deformer |
CStatus SetDeformerWeights2 | ( | X3DObject & | in_Deformer, |
const CDoubleArray & | in_Array | ||
) |
Sets the weights of the specified deformer without normalizing the weights.
in_Deformer | The deformer to set |
in_Array | Array of weight values to apply |
// This example shows how to set vertex envelope weights // on a deformer without normalizing the weights // Create the scene made of a cube and 2 nulls using namespace XSI; Application app; Model root = app.GetActiveSceneRoot(); X3DObject myCube; root.AddGeometry( L"Cube", L"MeshSurface", L"", myCube ); Parameter param( myCube.GetKinematics().GetGlobal().GetParameters().GetItem( L"posz" ) ); param.PutValue( (double)2.0 ); Null myDeformer1; root.AddNull( L"", myDeformer1 ); Null myDeformer2; root.AddNull( L"", myDeformer2 ); KinematicState nullGlobalKineState( myDeformer1.GetKinematics().GetGlobal() ); param = nullGlobalKineState.GetParameters().GetItem( L"posx" ); param.PutValue( (double)4.0 ); param = nullGlobalKineState.GetParameters().GetItem( L"posy" ); param.PutValue( (double)3.0 ); // Create a deformer array made of the 2 nulls CRefArray deformers( 2 ); deformers[ 0 ] = myDeformer1; deformers[ 1 ] = myDeformer2; // Create a Envelope Weight on the grid with the 2 nulls Envelope myEnvelope; myCube.ApplyEnvelope( deformers, siUnspecified, siUnspecified, myEnvelope ); // Get the first deformer and its weights at frame 0 X3DObject firstDeformer( myEnvelope.GetDeformers()[ 0 ] ); CDoubleArray weightsFirstDeformer = myEnvelope.GetDeformerWeights( firstDeformer, 0.0 ); // Set the first deformer weights to 10 for the current frame // without normalizing the weights LONG weightCount = weightsFirstDeformer.GetCount(); for( LONG i = 0; i < weightCount; i++ ) weightsFirstDeformer[ i ] = 10.0; myEnvelope.SetDeformerWeights2( firstDeformer, weightsFirstDeformer ); wchar_t msg[ 1024 ]; CRefArray myDeformers = myEnvelope.GetDeformers(); LONG deformerCount = myDeformers.GetCount(); CTime frame; // Get the second deformer X3DObject secondDeformer( myEnvelope.GetDeformers()[ 1 ] ); // Get the weights of both deformers weightsFirstDeformer = myEnvelope.GetDeformerWeights( firstDeformer, frame.GetTime() ); CDoubleArray weightsSecondDeformer = myEnvelope.GetDeformerWeights( secondDeformer, frame.GetTime() ); for( LONG i = 0; i < weightCount; i ++ ) { swprintf( msg, L"Vertex %i: Deformer 1: %4.1f, Deformer 2: %4.1f", i, weightsFirstDeformer[ i ], weightsSecondDeformer[ i ] ); app.LogMessage( msg ); }