About

A morph can use the mixing mode "Correctional PSD" (Pose Space Deformation). A CAReferencePSD object allows to access the related data. The class is defined in the lib_ca.h header file.

Access

The CAReferencePSD object is obtained from the CAMorphNode object, see CAMorphNode Points.

// This example accesses the PSD data of the given point morph.
// expand data to access it
morph->SetMode(doc, poseMorphTag, expandFlags, CAMORPH_MODE_ABS);
// check stored data
{
// get PSD data
if (psd)
{
// loop through all controllers
const Int32 controllerCount = psd->GetExternalControllerCount();
for (Int32 controllerIndex = 0; controllerIndex < controllerCount; ++controllerIndex)
{
BaseObject* controller = psd->GetExternalController(controllerIndex);
if (controller)
{
GePrint("Controller: " + controller->GetName());
}
}
}
}
// collapse data
morph->SetMode(doc, poseMorphTag, collapseFlags, CAMORPH_MODE_AUTO);

Interpolation

For autoweighting an interpolation mode is used:

The modes are:

// This example switches the interpolation setting
// of the given CAReferencePSD.
if (interpolation == CAMORPH_PSDINTERPOLATION_MODE_AXIS)

Driver

The joints referenced in the used weight tag can be forced to work as drivers for the PSD.

// This example loops through all joints weighted in the
// referenced Weight tag. All joints are forced as drivers.
GeData data;
C4DAtom* wTag = data.GetLinkAtom(doc, Tweights);
if (wTag)
{
CAWeightTag* weightTag = static_cast<CAWeightTag*>(wTag);
const Int32 jointCount = weightTag->GetJointCount();
for (Int32 jointIndex = 0; jointIndex < jointCount; ++jointIndex)
{
psd->ForceJointAsDriver(jointIndex, true);
}
}

Pose

The PSD is based on a skeleton reference pose.

// This example restores the reference pose of the CAReferencePSD.
// get PSD data
if (psd)
{
}

Controllers

Non-joint objects can also be used as controllers.

// This example sets all selected non joint objects
// as a controller object of the given point morph.
// get PSD data
if (psd)
{
if (objects)
{
// get selected objects
// loop through all objects
const Int32 objectCount = objects->GetCount();
for (Int32 i = 0; i < objectCount; ++i)
{
C4DAtom* atom = objects->GetIndex(i);
BaseObject* baseObject = static_cast<BaseObject*>(atom);
// only add non-joint objects
if (baseObject && !baseObject->IsInstanceOf(Ojoint))
{
// add object as controller
const Matrix mg = baseObject->GetMg();
psd->SetExternalControllerMatrix(baseObject, mg);
}
}
}
}

Further Reading