About

A morph can use the mixing mode "Correctional PSD" (Pose Space Deformation). A CAReferencePSD object allows accessing 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
CAReferencePSD* const psd = mnode->GetPSDReference();
if (psd)
{
// loop through all controllers
const Int32 controllerCount = psd->GetExternalControllerCount();
for (Int32 controllerIndex = 0; controllerIndex < controllerCount; ++controllerIndex)
{
BaseObject* const controller = psd->GetExternalController(controllerIndex);
if (controller == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
ApplicationOutput("Controller: " + controller->GetName());
}
}
}
// collapse data
morph->SetMode(doc, poseMorphTag, collapseFlags, CAMORPH_MODE::AUTO);

Interpolation

For auto-weighting an interpolation mode is used:

The modes are:

// This example switches the interpolation setting
// of the given CAReferencePSD.

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* const wTag = data.GetLinkAtom(doc, Tweights);
if (wTag)
{
CAWeightTag* const 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
CAReferencePSD* const psd = mnode->GetPSDReference();
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
CAReferencePSD* const psd = mnode->GetPSDReference();
if (psd)
{
if (objects)
{
// get selected objects
// loop through all objects
const Int32 objectCount = objects->GetCount();
for (Int32 i = 0; i < objectCount; ++i)
{
C4DAtom* const atom = objects->GetIndex(i);
BaseObject* const 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

CAReferencePSD::GetExternalController
BaseObject * GetExternalController(Int32 controllerIndex)
GeData::GetLinkAtom
C4DAtomGoal * GetLinkAtom(const BaseDocument *doc, Int32 instanceof=0) const
BaseObject
Definition: c4d_baseobject.h:224
maxon::Mat3< maxon::Vector64 >
CAReferencePSD::GetInterpolationMode
CAMORPH_PSDINTERPOLATION_MODE GetInterpolationMode() const
Tweights
#define Tweights
Weights.
Definition: ge_prepass.h:1285
CAMORPH_MODE::AUTO
@ AUTO
Auto mode. Used to collapse the data automatically into their correct mode.
BaseObject::GetMg
Matrix GetMg() const
Definition: c4d_baseobject.h:482
GETACTIVEOBJECTFLAGS::NONE
@ NONE
None.
CAMORPH_PSDINTERPOLATION_MODE::JOINT
@ JOINT
Per joint interpolation (joint axis average).
AtomArray::GetCount
Int32 GetCount() const
Definition: c4d_baselist.h:1648
CAWeightTag
Definition: lib_ca.h:178
MAXON_SOURCE_LOCATION
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:66
CAWeightTag::GetJointCount
Int32 GetJointCount()
CAMORPH_PSDINTERPOLATION_MODE::AXIS
@ AXIS
Per joint axis.
CAMorph::SetMode
Bool SetMode(BaseDocument *doc, CAPoseMorphTag *tag, CAMORPH_MODE_FLAGS flags, CAMORPH_MODE mode)
CAReferencePSD::ForceJointAsDriver
Bool ForceJointAsDriver(Int32 jointIndex, Bool forceDriver)
CAReferencePSD::RestoreReferencePose
void RestoreReferencePose()
Displays skeleton and user defined controller at the reference pose.
CAMORPH_DATA_FLAGS::POINTS
@ POINTS
Points morphing.
ID_CA_POSE_WEIGHTTAG_UI_ONLY
@ ID_CA_POSE_WEIGHTTAG_UI_ONLY
Definition: tcaposemorph.h:54
BaseDocument::GetActiveObjects
void GetActiveObjects(AtomArray &selection, GETACTIVEOBJECTFLAGS flags) const
CAMorphNode::GetInfo
CAMORPH_DATA_FLAGS GetInfo()
GeData
Definition: c4d_gedata.h:82
C4DAtom
Definition: c4d_baselist.h:1360
Int32
maxon::Int32 Int32
Definition: ge_sys_math.h:60
ApplicationOutput
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:208
CAMORPH_MODE_FLAGS::ALL
@ ALL
Expand or collapse all data.
CAReferencePSD::SetExternalControllerMatrix
Int32 SetExternalControllerMatrix(BaseObject *controller, const Matrix &globalMatrix)
CAReferencePSD::GetExternalControllerCount
Int32 GetExternalControllerCount() const
CAReferencePSD
Definition: lib_ca.h:923
CAMorphNode::GetPSDReference
CAReferencePSD * GetPSDReference()
AutoAlloc
Definition: ge_autoptr.h:36
DESCFLAGS_GET::NONE
@ NONE
None.
C4DAtom::IsInstanceOf
Bool IsInstanceOf(Int32 id) const
Definition: c4d_baselist.h:1402
BaseList2D::GetName
String GetName() const
Definition: c4d_baselist.h:2347
CAMORPH_MODE_FLAGS
CAMORPH_MODE_FLAGS
Definition: lib_ca.h:849
CAMORPH_PSDINTERPOLATION_MODE
CAMORPH_PSDINTERPOLATION_MODE
Definition: lib_ca.h:907
CAReferencePSD::SetInterpolationMode
void SetInterpolationMode(CAMORPH_PSDINTERPOLATION_MODE interpMode)
CAMORPH_MODE::ABS
@ ABS
Absolute morph data.
C4DAtom::GetParameter
Bool GetParameter(const DescID &id, GeData &t_data, DESCFLAGS_GET flags)
CAMORPH_MODE_FLAGS::EXPAND
@ EXPAND
Expand data. Needs to be passed before accessing any data.
CAMORPH_MODE_FLAGS::COLLAPSE
@ COLLAPSE
Collapse data. Needs to be passed to collapse the expanded data, for instance after data access.
Ojoint
#define Ojoint
Joint.
Definition: ge_prepass.h:1036
AtomArray::GetIndex
C4DAtom * GetIndex(Int32 idx) const
Definition: c4d_baselist.h:1663