Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add aim and PV direction vectors, to support skeletons that have different joint orientations. #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 64 additions & 4 deletions grim_vik.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ MObject Grim_VIK::iLengthBoost;
MObject Grim_VIK::iSoftness;
MObject Grim_VIK::iTwist;

MObject Grim_VIK::iAimDirection;
MObject Grim_VIK::iPoleVectorDirection;

MObject Grim_VIK::oOutTranslate;
MObject Grim_VIK::oOutRotateX;
MObject Grim_VIK::oOutRotateY;
Expand Down Expand Up @@ -68,7 +71,8 @@ MStatus Grim_VIK::setDependentsDirty( const MPlug &plugBeingDirtied, MPlugArray
*/

// ----------------------------------------------------------------------
inline void Grim_VIK::calculate_orientations( Pose &pose, const MPoint &pole_point, const bool flip ) {
inline void Grim_VIK::calculate_orientations( Pose &pose, const MPoint &pole_point,
const MVector &aimDirection, const MVector &poleVectorDirection ) {
MVector upper_vector = (pose.position[1] - pose.position[0]);
MVector lower_vector = (pose.position[2] - pose.position[1]);
MVector goal_vector = (pose.position[2] - pose.position[0]);
Expand All @@ -82,9 +86,25 @@ inline void Grim_VIK::calculate_orientations( Pose &pose, const MPoint &pole_poi
pole_vector.normalize();

MVector side_vector = goal_vector ^ pole_vector;
side_vector.normalize();

auto create_rotation_matrix = [aimDirection, poleVectorDirection]( const MVector &aim, const MVector &up )
{
// aim is down the joint. aim^up is towards the pole vector.
MVector pv = up ^ aim;

// aimVectorDirection is the direction down the joint, and poleVectorDirection
// points towards the pole vector. Take the cross product of these.
MVector upVectorDirection = aimDirection ^ poleVectorDirection;

MVector xVector = aim*aimDirection[0] + pv*poleVectorDirection[0] + up*upVectorDirection[0];
MVector yVector = aim*aimDirection[1] + pv*poleVectorDirection[1] + up*upVectorDirection[1];
MVector zVector = aim*aimDirection[2] + pv*poleVectorDirection[2] + up*upVectorDirection[2];
return matrix_from_three_vectors( xVector, yVector, zVector );
};

pose.orientation[0] = MTransformationMatrix(matrix_from_two_vectors(upper_vector, side_vector, flip)).rotation();
pose.orientation[1] = MTransformationMatrix(matrix_from_two_vectors(lower_vector, side_vector, flip)).rotation();
pose.orientation[0] = MTransformationMatrix(create_rotation_matrix(upper_vector, side_vector)).rotation();
pose.orientation[1] = MTransformationMatrix(create_rotation_matrix(lower_vector, side_vector)).rotation();
}


Expand Down Expand Up @@ -127,6 +147,9 @@ MStatus Grim_VIK::compute( const MPlug& plug, MDataBlock& data )
double softness = data.inputValue(iSoftness).asDouble();
double twist = data.inputValue(iTwist).asDouble();

MVector aimDirection = data.inputValue(iAimDirection).asVector();
MVector poleVectorDirection = data.inputValue(iPoleVectorDirection).asDouble3();

// new favorite trick of stealing scale from root matrix instead of pumping in a compensate value
double scale_compensate = MVector(rootMatrix[0][0], rootMatrix[0][1], rootMatrix[0][2]).length();
double inverse_scale = 1.0 / scale_compensate;
Expand Down Expand Up @@ -313,7 +336,16 @@ MStatus Grim_VIK::compute( const MPlug& plug, MDataBlock& data )
}
}

calculate_orientations( ik_pose, polePos, flipOrientation );
// If flipOrientation is true, flip the aim and pole vector directions the other
// way. This is for compatibility and it's better to just set the attributes.
if( flipOrientation )
{
aimDirection *= -1;
poleVectorDirection *= -1;
}
aimDirection.normalize();
poleVectorDirection.normalize();
calculate_orientations( ik_pose, polePos, aimDirection, poleVectorDirection );

// tip orientation based on blend, not vectors
if (orientTipBlend == 0.0) {
Expand Down Expand Up @@ -621,6 +653,32 @@ MStatus Grim_VIK::initialize()
}
}

MObject iAimDirectionX = nAttr.create( "aimDirectionX", "aimDirectionX", MFnNumericData::kDouble, 1.0 );
nAttr.setCached(true);
MObject iAimDirectionY = nAttr.create( "aimDirectionY", "aimDirectionY", MFnNumericData::kDouble, 0.0 );
nAttr.setCached(true);
MObject iAimDirectionZ = nAttr.create( "aimDirectionZ", "aimDirectionZ", MFnNumericData::kDouble, 0.0 );
nAttr.setCached(true);
iAimDirection = nAttr.create( "aimDirection", "aimDirection", iAimDirectionX, iAimDirectionY, iAimDirectionZ );
nAttr.setCached(true);
CHECK_MSTATUS_AND_RETURN_IT( addAttribute(iAimDirection) );

MObject iPoleVectorDirectionX = nAttr.create( "poleVectorDirectionX", "poleVectorDirectionX", MFnNumericData::kDouble, 0.0 );
nAttr.setCached(true);
MObject iPoleVectorDirectionY = nAttr.create( "poleVectorDirectionY", "poleVectorDirectionY", MFnNumericData::kDouble, 1.0 );
nAttr.setCached(true);
MObject iPoleVectorDirectionZ = nAttr.create( "poleVectorDirectionZ", "poleVectorDirectionZ", MFnNumericData::kDouble, 0.0 );
nAttr.setCached(true);
iPoleVectorDirection = nAttr.create( "poleVectorDirection", "poleVectorDirection", iPoleVectorDirectionX, iPoleVectorDirectionY, iPoleVectorDirectionZ );
nAttr.setCached(true);
CHECK_MSTATUS_AND_RETURN_IT( addAttribute(iPoleVectorDirection) );

for (const auto &output_pair : all_outputs)
{
CHECK_MSTATUS_AND_RETURN_IT( attributeAffects(iAimDirection, *output_pair.second) );
CHECK_MSTATUS_AND_RETURN_IT( attributeAffects(iPoleVectorDirection, *output_pair.second) );
}

return MS::kSuccess;
}

Expand All @@ -642,6 +700,8 @@ void Grim_VIK::aeTemplate() {
editorTemplate -addControl "lowerLengthBoost";
editorTemplate -addControl "lengthBoost";
editorTemplate -addControl "softness";
editorTemplate -addControl "aimDirection";
editorTemplate -addControl "poleVectorDirection";
editorTemplate -endLayout;

AEdependNodeTemplate $nodeName;
Expand Down
5 changes: 4 additions & 1 deletion grim_vik.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Grim_VIK : public MPxNode

virtual MStatus compute( const MPlug& plug, MDataBlock& data );

inline void calculate_orientations( Pose &pose, const MPoint &pole_point, const bool flip );
inline void calculate_orientations( Pose &pose, const MPoint &pole_point, const MVector &aimVectorDirection, const MVector &poleVectorDirection );

static void* creator();
static MStatus initialize();
Expand Down Expand Up @@ -52,6 +52,9 @@ class Grim_VIK : public MPxNode
static MObject iSoftness;
static MObject iTwist;

static MObject iAimDirection;
static MObject iPoleVectorDirection;

// outputs
static MObject oOutTranslate;
static MObject oOutRotateX;
Expand Down