#include "util.h"
#include "XformHelper.h"
#include "NodeIteratorVisitorHelper.h"
#include <Alembic/AbcGeom/IXform.h>
#include <maya/MObject.h>
#include <maya/MEulerRotation.h>
#include <maya/MFnTransform.h>
#include <maya/MMatrix.h>
#include <maya/MPoint.h>
#include <maya/MQuaternion.h>
#include <maya/MString.h>
#include <maya/MTransformationMatrix.h>
#include <maya/MVector.h>
#include <maya/MGlobal.h>
#include <maya/MDagModifier.h>
namespace
{
const bool gBalance = false;
};
void readComplex(double iFrame, Alembic::AbcGeom::IXform & iNode,
std::vector<double> & oSampleList)
{
Alembic::AbcCoreAbstract::index_t index, ceilIndex;
double alpha = getWeightAndIndex(iFrame,
iNode.getSchema().getTimeSampling(),
iNode.getSchema().getNumSamples(),
index, ceilIndex);
Alembic::Abc::M44d m;
if (alpha != 0.0 && index != ceilIndex)
{
Alembic::AbcGeom::XformSample samp;
iNode.getSchema().get(samp, Alembic::Abc::ISampleSelector(index));
Alembic::Abc::M44d mlo = samp.getMatrix();
iNode.getSchema().get(samp, Alembic::Abc::ISampleSelector(ceilIndex));
Alembic::Abc::M44d mhi = samp.getMatrix();
m = ((1 - alpha) * mlo) + (alpha * mhi);
}
else
{
Alembic::AbcGeom::XformSample samp;
iNode.getSchema().get(samp, Alembic::Abc::ISampleSelector(index));
m = samp.getMatrix();
}
MVector vec = mmat.getTranslation(tSpace);
oSampleList.push_back(vec.
x);
oSampleList.push_back(vec.
y);
oSampleList.push_back(vec.
z);
vec = mmat.rotatePivotTranslation(tSpace);
oSampleList.push_back(vec.
x);
oSampleList.push_back(vec.
y);
oSampleList.push_back(vec.
z);
MPoint pt = mmat.rotatePivot(tSpace);
oSampleList.push_back(pt.
x);
oSampleList.push_back(pt.
y);
oSampleList.push_back(pt.
z);
double rot[3];
mmat.getRotation(rot, order);
oSampleList.push_back(Alembic::AbcGeom::RadiansToDegrees(rot[0]));
oSampleList.push_back(Alembic::AbcGeom::RadiansToDegrees(rot[1]));
oSampleList.push_back(Alembic::AbcGeom::RadiansToDegrees(rot[2]));
oSampleList.push_back(Alembic::AbcGeom::RadiansToDegrees(vec.
x));
oSampleList.push_back(Alembic::AbcGeom::RadiansToDegrees(vec.
y));
oSampleList.push_back(Alembic::AbcGeom::RadiansToDegrees(vec.
z));
pt = mmat.scalePivotTranslation(tSpace);
oSampleList.push_back(vec.
x);
oSampleList.push_back(vec.
y);
oSampleList.push_back(vec.
z);
vec = mmat.scalePivot(tSpace);
oSampleList.push_back(vec.
x);
oSampleList.push_back(vec.
y);
oSampleList.push_back(vec.
z);
double shear[3];
mmat.getShear(shear, tSpace);
oSampleList.push_back(shear[0]);
oSampleList.push_back(shear[1]);
oSampleList.push_back(shear[2]);
double scale[3];
mmat.getScale(scale, tSpace);
oSampleList.push_back(scale[0]);
oSampleList.push_back(scale[1]);
oSampleList.push_back(scale[2]);
}
void read(double iFrame, Alembic::AbcGeom::IXform & iNode,
std::vector<double> & oSampleList,
Alembic::AbcGeom::XformSample & oSamp)
{
Alembic::AbcCoreAbstract::index_t index, ceilIndex;
double alpha = getWeightAndIndex(iFrame,
iNode.getSchema().getTimeSampling(),
iNode.getSchema().getNumSamples(), index, ceilIndex);
if (alpha != 0 && index != ceilIndex &&
!iNode.getSchema().isConstant())
{
iNode.getSchema().
get(oSamp, Alembic::Abc::ISampleSelector(index));
Alembic::AbcGeom::XformSample hiSamp;
iNode.getSchema().get(hiSamp,
Alembic::Abc::ISampleSelector(ceilIndex));
std::vector<double> loVec, hiVec;
size_t numOps = oSamp.getNumOps();
for (size_t i = 0; i < numOps; ++i)
{
Alembic::AbcGeom::XformOp loOp = oSamp[i];
Alembic::AbcGeom::XformOp hiOp = hiSamp[i];
size_t numChannels = loOp.getNumChannels();
for (size_t j = 0; j < numChannels; ++j)
{
if (loOp.isChannelAnimated(j))
{
loVec.push_back(loOp.getChannelValue(j));
hiVec.push_back(hiOp.getChannelValue(j));
}
}
}
size_t numAnim = loVec.size();
oSampleList.resize(numAnim);
for (size_t i = 0; i < numAnim; ++i)
{
oSampleList[i] = simpleLerp<double>(alpha,loVec[i], hiVec[i]);
}
}
else
{
iNode.getSchema().get(oSamp, Alembic::Abc::ISampleSelector(index));
size_t numOps = oSamp.getNumOps();
for (size_t i = 0; i < numOps; ++i)
{
Alembic::AbcGeom::XformOp op = oSamp[i];
size_t numChannels = op.getNumChannels();
for (size_t j = 0; j < numChannels; ++j)
{
if (op.isChannelAnimated(j))
{
oSampleList.push_back(op.getChannelValue(j));
}
}
}
}
}
bool isComplex(const Alembic::AbcGeom::XformSample & iSamp)
{
int state = 0;
bool scPivot = false;
bool roPivot = false;
bool xAxis = false;
bool yAxis = false;
bool zAxis = false;
size_t numOps = iSamp.getNumOps();
for (size_t i = 0; i < numOps; ++i)
{
Alembic::AbcGeom::XformOp op = iSamp[i];
switch (op.getType())
{
case Alembic::AbcGeom::kScaleOperation:
{
if (state < 12)
{
state = 12;
}
else
return true;
}
break;
case Alembic::AbcGeom::kTranslateOperation:
{
switch (op.getHint())
{
case Alembic::AbcGeom::kTranslateHint:
{
if (state < 1)
state = 1;
else
return true;
}
break;
case Alembic::AbcGeom::kScalePivotPointHint:
{
if (state < 10 && !scPivot)
{
scPivot = true;
state = 10;
}
else if (state < 13 && scPivot)
{
scPivot = false;
state = 13;
}
else
return true;
}
break;
case Alembic::AbcGeom::kScalePivotTranslationHint:
{
if (state < 9)
state = 9;
else
return true;
}
break;
case Alembic::AbcGeom::kRotatePivotPointHint:
{
if (state < 3 && !roPivot)
{
roPivot = true;
state = 3;
}
else if (state < 8 && roPivot)
{
roPivot = false;
state = 8;
}
else
return true;
}
break;
case Alembic::AbcGeom::kRotatePivotTranslationHint:
{
if (state < 2)
state = 2;
else
return true;
}
break;
default:
return true;
break;
}
}
break;
case Alembic::AbcGeom::kRotateXOperation:
case Alembic::AbcGeom::kRotateYOperation:
case Alembic::AbcGeom::kRotateZOperation:
case Alembic::AbcGeom::kRotateOperation:
{
if (op.isXAnimated() || op.isYAnimated() || op.isZAnimated())
return true;
Alembic::Abc::V3d v = op.getAxis();
switch (op.getHint())
{
case Alembic::AbcGeom::kRotateHint:
{
if (v.x == 1 && v.y == 0 && v.z == 0 &&
!xAxis && state <= 4)
{
state = 4;
xAxis = true;
}
else if (v.x == 0 && v.y == 1 && v.z == 0 && !yAxis &&
state <= 4)
{
state = 4;
yAxis = true;
}
else if (v.x == 0 && v.y == 0 && v.z == 1 && !zAxis &&
state <= 4)
{
state = 4;
zAxis = true;
}
else
return true;
}
break;
case Alembic::AbcGeom::kRotateOrientationHint:
{
if (v.x == 1 && v.y == 0 && v.z == 0 && state < 7)
{
state = 7;
}
else if (v.x == 0 && v.y == 1 && v.z == 0 && state < 6)
{
state = 6;
}
else if (v.x == 0 && v.y == 0 && v.z == 1 && state < 5)
{
state = 5;
}
else
return true;
}
break;
default:
return true;
break;
}
}
break;
case Alembic::AbcGeom::kMatrixOperation:
{
if (op.getHint() == Alembic::AbcGeom::kMayaShearHint &&
state < 11)
{
state = 11;
}
else
return true;
}
break;
default:
{
return true;
}
break;
}
}
return scPivot || roPivot;
}
MStatus connectToXform(
const Alembic::AbcGeom::XformSample & iSamp,
bool isConstant,
std::vector<std::string> & oSampledTransOpNameList,
std::vector<Prop> & iSampledPropList,
std::size_t iFirstProp)
{
const double zero[3] = {0, 0, 0};
dstPlug = trans.
findPlug(
"scalePivotX");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"scalePivotY");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"scalePivotZ");
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
const double scale[3] = {1, 1, 1};
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"scalePivotTranslateX");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"scalePivotTranslateY");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"scalePivotTranslateZ");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotatePivotX");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotatePivotY");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotatePivotZ");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotateAxisX");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotateAxisY");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotateAxisZ");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotateOrder");
disconnectAllPlugsTo(dstPlug);
bool reorder = true;
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotatePivotTranslateX");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotatePivotTranslateY");
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"rotatePivotTranslateZ");
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
disconnectAllPlugsTo(dstPlug);
dstPlug = trans.
findPlug(
"inheritsTransform");
disconnectAllPlugsTo(dstPlug);
dstPlug.
setBool(iSamp.getInheritsXforms());
disconnectProps(trans, iSampledPropList, iFirstProp);
if (isComplex(iSamp))
{
if (!isConstant)
{
oSampledTransOpNameList.push_back("translateX");
oSampledTransOpNameList.push_back("translateY");
oSampledTransOpNameList.push_back("translateZ");
oSampledTransOpNameList.push_back("rotatePivotTranslateX");
oSampledTransOpNameList.push_back("rotatePivotTranslateY");
oSampledTransOpNameList.push_back("rotatePivotTranslateZ");
oSampledTransOpNameList.push_back("rotatePivotX");
oSampledTransOpNameList.push_back("rotatePivotY");
oSampledTransOpNameList.push_back("rotatePivotZ");
oSampledTransOpNameList.push_back("rotateX");
oSampledTransOpNameList.push_back("rotateY");
oSampledTransOpNameList.push_back("rotateZ");
oSampledTransOpNameList.push_back("rotateAxisX");
oSampledTransOpNameList.push_back("rotateAxisY");
oSampledTransOpNameList.push_back("rotateAxisZ");
oSampledTransOpNameList.push_back("scalePivotTranslateX");
oSampledTransOpNameList.push_back("scalePivotTranslateY");
oSampledTransOpNameList.push_back("scalePivotTranslateZ");
oSampledTransOpNameList.push_back("scalePivotX");
oSampledTransOpNameList.push_back("scalePivotY");
oSampledTransOpNameList.push_back("scalePivotZ");
oSampledTransOpNameList.push_back("shearXY");
oSampledTransOpNameList.push_back("shearXZ");
oSampledTransOpNameList.push_back("shearYZ");
oSampledTransOpNameList.push_back("scaleX");
oSampledTransOpNameList.push_back("scaleY");
oSampledTransOpNameList.push_back("scaleZ");
}
Alembic::Abc::M44d m = iSamp.getMatrix();
mmat.rotatePivotTranslation(tSpace), tSpace);
mmat.rotatePivot(tSpace), tSpace, gBalance);
mmat.rotationOrientation(), tSpace, gBalance);
mmat.scalePivotTranslation(tSpace), tSpace);
mmat.scalePivot(tSpace), tSpace, gBalance);
double shear[3];
mmat.getShear(shear, tSpace);
double scale[3];
mmat.getScale(scale, tSpace);
return status;
}
bool scPivot = false;
bool roPivot = false;
size_t numOps = iSamp.getNumOps();
for (size_t i = 0; i < numOps; ++i)
{
Alembic::AbcGeom::XformOp op = iSamp[i];
switch (op.getType())
{
case Alembic::AbcGeom::kScaleOperation:
{
double scale[3];
if (op.isXAnimated())
{
oSampledTransOpNameList.push_back("scaleX");
}
scale[0] = op.getChannelValue(0);
if (op.isYAnimated())
{
oSampledTransOpNameList.push_back("scaleY");
}
scale[1] = op.getChannelValue(1);
if (op.isZAnimated())
{
oSampledTransOpNameList.push_back("scaleZ");
}
scale[2] = op.getChannelValue(2);
}
break;
case Alembic::AbcGeom::kRotateXOperation:
case Alembic::AbcGeom::kRotateYOperation:
case Alembic::AbcGeom::kRotateZOperation:
case Alembic::AbcGeom::kRotateOperation:
{
Alembic::Abc::V3d axis = op.getAxis();
double x = axis.x;
double y = axis.y;
double z = axis.z;
double angle = 0.0;
if (op.getHint() == Alembic::AbcGeom::kRotateHint)
{
if (x == 1 && y == 0 && z == 0)
{
if (op.isAngleAnimated())
{
oSampledTransOpNameList.push_back("rotateX");
}
angle = op.getAngle();
rot.
x = Alembic::AbcGeom::DegreesToRadians(angle);
{
}
{
{
rotOrder[0] = rotOrder[1];
}
}
}
else if (x == 0 && y == 1 && z == 0)
{
if (op.isAngleAnimated())
{
oSampledTransOpNameList.push_back("rotateY");
}
angle = op.getAngle();
rot.
y = Alembic::AbcGeom::DegreesToRadians(angle);
{
}
{
{
rotOrder[0] = rotOrder[1];
}
}
}
else if (x == 0 && y == 0 && z == 1)
{
if (op.isAngleAnimated())
{
oSampledTransOpNameList.push_back("rotateZ");
}
angle = op.getAngle();
rot.
z = Alembic::AbcGeom::DegreesToRadians(angle);
{
}
{
{
rotOrder[0] = rotOrder[1];
}
}
}
}
else
{
if (x == 1 && y == 0 && z == 0)
{
if (op.isAngleAnimated())
{
oSampledTransOpNameList.push_back("rotateAxisX");
}
angle = op.getAngle();
Alembic::AbcGeom::DegreesToRadians(angle));
}
else if (x == 0 && y == 1 && z == 0)
{
if (op.isAngleAnimated())
{
oSampledTransOpNameList.push_back("rotateAxisY");
}
angle = op.getAngle();
Alembic::AbcGeom::DegreesToRadians(angle));
}
else if (x == 0 && y == 0 && z == 1)
{
if (op.isAngleAnimated())
{
oSampledTransOpNameList.push_back("rotateAxisZ");
}
angle = op.getAngle();
Alembic::AbcGeom::DegreesToRadians(angle));
}
}
}
break;
case Alembic::AbcGeom::kMatrixOperation:
{
double shear[3];
if (op.isChannelAnimated(4))
{
oSampledTransOpNameList.push_back("shearXY");
}
shear[0] = op.getChannelValue(4);
if (op.isChannelAnimated(8))
{
oSampledTransOpNameList.push_back("shearXZ");
}
shear[1] = op.getChannelValue(8);
if (op.isChannelAnimated(9))
{
oSampledTransOpNameList.push_back("shearYZ");
}
shear[2] = op.getChannelValue(9);
}
break;
case Alembic::AbcGeom::kTranslateOperation:
{
Alembic::Util::uint8_t hint = op.getHint();
switch (hint)
{
case Alembic::AbcGeom::kTranslateHint:
{
if (op.isXAnimated())
{
oSampledTransOpNameList.push_back("translateX");
}
vec.
x = op.getChannelValue(0);
if (op.isYAnimated())
{
oSampledTransOpNameList.push_back("translateY");
}
vec.
y = op.getChannelValue(1);
if (op.isZAnimated())
{
oSampledTransOpNameList.push_back("translateZ");
}
vec.
z = op.getChannelValue(2);
}
break;
case Alembic::AbcGeom::kScalePivotPointHint:
{
if (op.isXAnimated())
{
if (!scPivot)
{
oSampledTransOpNameList.push_back(
"scalePivotX");
}
else
{
oSampledTransOpNameList.push_back(
"scalePivotXInv");
}
}
point.
x = op.getChannelValue(0);
if (op.isYAnimated())
{
if (!scPivot)
{
oSampledTransOpNameList.push_back(
"scalePivotY");
}
else
{
oSampledTransOpNameList.push_back(
"scalePivotYInv");
}
}
point.
y = op.getChannelValue(1);
if (op.isZAnimated())
{
if (!scPivot)
{
oSampledTransOpNameList.push_back(
"scalePivotZ");
}
else
{
oSampledTransOpNameList.push_back(
"scalePivotZInv");
}
}
point.
z = op.getChannelValue(2);
if (!scPivot)
{
}
scPivot = !scPivot;
}
break;
case Alembic::AbcGeom::kScalePivotTranslationHint:
{
if (op.isXAnimated())
{
oSampledTransOpNameList.push_back(
"scalePivotTranslateX");
}
vec.
x = op.getChannelValue(0);
if (op.isYAnimated())
{
oSampledTransOpNameList.push_back(
"scalePivotTranslateY");
}
vec.
y = op.getChannelValue(1);
if (op.isZAnimated())
{
oSampledTransOpNameList.push_back(
"scalePivotTranslateZ");
}
vec.
z = op.getChannelValue(2);
}
break;
case Alembic::AbcGeom::kRotatePivotPointHint:
{
if (op.isXAnimated())
{
if (!roPivot)
{
oSampledTransOpNameList.push_back(
"rotatePivotX");
}
else
{
oSampledTransOpNameList.push_back(
"rotatePivotXInv");
}
}
point.
x = op.getChannelValue(0);
if (op.isYAnimated())
{
if (!roPivot)
{
oSampledTransOpNameList.push_back(
"rotatePivotY");
}
else
{
oSampledTransOpNameList.push_back(
"rotatePivotYInv");
}
}
point.
y = op.getChannelValue(1);
if (op.isZAnimated())
{
if (!roPivot)
{
oSampledTransOpNameList.push_back(
"rotatePivotZ");
}
else
{
oSampledTransOpNameList.push_back(
"rotatePivotZInv");
}
}
point.
z = op.getChannelValue(2);
if (!roPivot)
roPivot = !roPivot;
}
break;
case Alembic::AbcGeom::kRotatePivotTranslationHint:
{
if (op.isXAnimated())
{
oSampledTransOpNameList.push_back(
"rotatePivotTranslateX");
}
vec.
x = op.getChannelValue(0);
if (op.isYAnimated())
{
oSampledTransOpNameList.push_back(
"rotatePivotTranslateY");
}
vec.
y = op.getChannelValue(1);
if (op.isZAnimated())
{
oSampledTransOpNameList.push_back(
"rotatePivotTranslateZ");
}
vec.
z = op.getChannelValue(2);
}
break;
default:
break;
}
}
break;
default:
break;
}
}
{
}
return status;
}