Skip to content

Commit

Permalink
Convert USD timeSamples to Maya FPS
Browse files Browse the repository at this point in the history
  • Loading branch information
dgovil committed Dec 11, 2020
1 parent ddcd319 commit a9674ae
Show file tree
Hide file tree
Showing 21 changed files with 463 additions and 42 deletions.
21 changes: 19 additions & 2 deletions lib/mayaUsd/fileio/jobs/readJob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ bool UsdMaya_ReadJob::Read(std::vector<MDagPath>* addedDagPaths)
}

stage->SetEditTarget(stage->GetSessionLayer());
_setTimeSampleMultiplierFrom(stage->GetTimeCodesPerSecond());

// XXX Currently all distance values are set directly from USD and will be
// interpreted as centimeters (Maya's internal distance unit). Future work
Expand Down Expand Up @@ -152,11 +153,14 @@ bool UsdMaya_ReadJob::Read(std::vector<MDagPath>* addedDagPaths)
stageInterval.SetMax(stage->GetEndTimeCode());
}

MTime::Unit timeUnit = MTime::uiUnit();
if (stageInterval.GetMin() < currentMinTime.value()) {
MAnimControl::setMinTime(MTime(stageInterval.GetMin()));
MAnimControl::setMinTime(
MTime(stageInterval.GetMin() * mTimeSampleMultiplier, timeUnit));
}
if (stageInterval.GetMax() > currentMaxTime.value()) {
MAnimControl::setMaxTime(MTime(stageInterval.GetMax()));
MAnimControl::setMaxTime(
MTime(stageInterval.GetMax() * mTimeSampleMultiplier, timeUnit));
}
}

Expand Down Expand Up @@ -391,6 +395,7 @@ void UsdMaya_ReadJob::_ImportMaster(
for (auto primIt = range.begin(); primIt != range.end(); ++primIt) {
const UsdPrim& prim = *primIt;
UsdMayaPrimReaderContext readCtx(&mNewNodeRegistry);
readCtx.SetTimeSampleMultiplier(mTimeSampleMultiplier);
if (prim.IsInstance()) {
_DoImportInstanceIt(primIt, usdRootPrim, readCtx, primReaderMap);
} else {
Expand Down Expand Up @@ -418,6 +423,7 @@ bool UsdMaya_ReadJob::_DoImport(UsdPrimRange& rootRange, const UsdPrim& usdRootP
for (auto primIt = range.begin(); primIt != range.end(); ++primIt) {
const UsdPrim& prim = *primIt;
UsdMayaPrimReaderContext readCtx(&mNewNodeRegistry);
readCtx.SetTimeSampleMultiplier(mTimeSampleMultiplier);

if (buildInstances && prim.IsInstance()) {
_DoImportInstanceIt(primIt, usdRootPrim, readCtx, primReaderMap);
Expand All @@ -430,6 +436,8 @@ bool UsdMaya_ReadJob::_DoImport(UsdPrimRange& rootRange, const UsdPrim& usdRootP
if (buildInstances) {
MDGModifier deleteMasterMod;
UsdMayaPrimReaderContext readCtx(&mNewNodeRegistry);
readCtx.SetTimeSampleMultiplier(mTimeSampleMultiplier);

for (const auto& master : usdRootPrim.GetStage()->GetMasters()) {
const SdfPath masterPath = master.GetPath();
MObject masterObject = readCtx.GetMayaNode(masterPath, false);
Expand Down Expand Up @@ -500,4 +508,13 @@ void UsdMaya_ReadJob::SetMayaRootDagPath(const MDagPath& mayaRootDagPath)

const MDagPath& UsdMaya_ReadJob::GetMayaRootDagPath() const { return mMayaRootDagPath; }

double UsdMaya_ReadJob::timeSampleMultiplier() const { return mTimeSampleMultiplier; }

double UsdMaya_ReadJob::_setTimeSampleMultiplierFrom(const double layerFPS)
{
float sceneFPS = UsdMayaUtil::GetSceneMTimeUnitAsFloat();
mTimeSampleMultiplier = sceneFPS / layerFPS;
return mTimeSampleMultiplier;
}

PXR_NAMESPACE_CLOSE_SCOPE
6 changes: 6 additions & 0 deletions lib/mayaUsd/fileio/jobs/readJob.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ class UsdMaya_ReadJob
MAYAUSD_CORE_PUBLIC
const MDagPath& GetMayaRootDagPath() const;

MAYAUSD_CORE_PUBLIC
double timeSampleMultiplier() const;

protected:
// Types
using _PrimReaderMap = std::unordered_map<SdfPath, UsdMayaPrimReaderSharedPtr, SdfPath::Hash>;
Expand Down Expand Up @@ -122,9 +125,12 @@ class UsdMaya_ReadJob
const UsdPrim& usdRootPrim,
UsdMayaPrimReaderContext& readCtx);

double _setTimeSampleMultiplierFrom(const double layerFPS);

// Data
MDagModifier mDagModifierUndo;
bool mDagModifierSeeded;
double mTimeSampleMultiplier;
};

PXR_NAMESPACE_CLOSE_SCOPE
Expand Down
8 changes: 8 additions & 0 deletions lib/mayaUsd/fileio/primReaderContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ PXR_NAMESPACE_OPEN_SCOPE

UsdMayaPrimReaderContext::UsdMayaPrimReaderContext(ObjectRegistry* pathNodeMap)
: _prune(false)
, _timeSampleMultiplier(1.0)
, _pathNodeMap(pathNodeMap)
{
}
Expand Down Expand Up @@ -61,4 +62,11 @@ bool UsdMayaPrimReaderContext::GetPruneChildren() const { return _prune; }
/// children have already been processed.
void UsdMayaPrimReaderContext::SetPruneChildren(bool prune) { _prune = prune; }

double UsdMayaPrimReaderContext::GetTimeSampleMultiplier() const { return _timeSampleMultiplier; };

void UsdMayaPrimReaderContext::SetTimeSampleMultiplier(double multiplier)
{
_timeSampleMultiplier = multiplier;
};

PXR_NAMESPACE_CLOSE_SCOPE
11 changes: 10 additions & 1 deletion lib/mayaUsd/fileio/primReaderContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,19 @@ class UsdMayaPrimReaderContext
MAYAUSD_CORE_PUBLIC
void SetPruneChildren(bool prune);

/// \brief Return the time sample multiplier to convert from USD time to Maya time
MAYAUSD_CORE_PUBLIC
double GetTimeSampleMultiplier() const;

/// \brief Set the time sample multiplier to convert from USD time to Maya time
MAYAUSD_CORE_PUBLIC
void SetTimeSampleMultiplier(double multiplier);

~UsdMayaPrimReaderContext() { }

private:
bool _prune;
bool _prune;
double _timeSampleMultiplier;

// used to keep track of prims that are created.
// for undo/redo
Expand Down
29 changes: 21 additions & 8 deletions lib/mayaUsd/fileio/translators/translatorCamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ static bool _GetTimeAndValueArrayForUsdAttribute(
const GfInterval& timeInterval,
MTimeArray* timeArray,
MDoubleArray* valueArray,
const MDistance::Unit convertToUnit = MDistance::kMillimeters)
const MDistance::Unit convertToUnit = MDistance::kMillimeters,
const double timeSampleMultiplier = 1.0)
{
static const TfType& floatType = TfType::Find<float>();
std::vector<double> timeSamples;
Expand All @@ -118,8 +119,8 @@ static bool _GetTimeAndValueArrayForUsdAttribute(
return false;
}

size_t numTimeSamples = timeSamples.size();

size_t numTimeSamples = timeSamples.size();
MTime::Unit timeUnit = MTime::uiUnit();
for (size_t i = 0; i < numTimeSamples; ++i) {
const double timeSample = timeSamples[i];
float attrValue;
Expand All @@ -135,7 +136,7 @@ static bool _GetTimeAndValueArrayForUsdAttribute(
break;
}

timeArray->set(MTime(timeSample), i);
timeArray->set(MTime(timeSample * timeSampleMultiplier, timeUnit), i);
valueArray->set(attrValue, i);
}

Expand All @@ -150,7 +151,8 @@ static bool _GetTimeAndValueArraysForUsdAttribute(
const GfInterval& timeInterval,
MTimeArray* timeArray,
MDoubleArray* valueArray1,
MDoubleArray* valueArray2)
MDoubleArray* valueArray2,
const double timeSampleMultiplier = 1.0)
{
static const TfType& vec2fType = TfType::Find<GfVec2f>();
std::vector<double> timeSamples;
Expand All @@ -162,14 +164,15 @@ static bool _GetTimeAndValueArraysForUsdAttribute(

size_t numTimeSamples = timeSamples.size();
valueArray2->setLength(numTimeSamples);
MTime::Unit timeUnit = MTime::uiUnit();

for (size_t i = 0; i < numTimeSamples; ++i) {
const double timeSample = timeSamples[i];
GfVec2f attrValue;
if (!usdAttr.Get(&attrValue, timeSample)) {
return false;
}
timeArray->set(MTime(timeSample), i);
timeArray->set(MTime(timeSample * timeSampleMultiplier, timeUnit), i);
valueArray1->set(attrValue[0], i);
valueArray2->set(attrValue[1], i);
}
Expand Down Expand Up @@ -213,7 +216,12 @@ static bool _TranslateAnimatedUsdAttributeToPlug(
MTimeArray timeArray;
MDoubleArray valueArray;
if (!_GetTimeAndValueArrayForUsdAttribute(
usdAttr, args.GetTimeInterval(), &timeArray, &valueArray, convertToUnit)) {
usdAttr,
args.GetTimeInterval(),
&timeArray,
&valueArray,
convertToUnit,
(context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0)) {
return false;
}

Expand All @@ -239,7 +247,12 @@ static bool _TranslateAnimatedUsdAttributeToPlugs(
MDoubleArray valueArray1;
MDoubleArray valueArray2;
if (!_GetTimeAndValueArraysForUsdAttribute(
usdAttr, args.GetTimeInterval(), &timeArray, &valueArray1, &valueArray2)) {
usdAttr,
args.GetTimeInterval(),
&timeArray,
&valueArray1,
&valueArray2,
(context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0)) {
return false;
}

Expand Down
7 changes: 4 additions & 3 deletions lib/mayaUsd/fileio/translators/translatorCurves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,11 @@ bool UsdMayaTranslatorCurves::Create(
MFnAnimCurve animFn;

// Construct the time array to be used for all the keys
MTimeArray timeArray;
timeArray.setLength(numTimeSamples);
MTime::Unit timeUnit = MTime::uiUnit();
double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0;
MTimeArray timeArray(numTimeSamples, MTime());
for (unsigned int ti = 0; ti < numTimeSamples; ++ti) {
timeArray.set(MTime(pointsTimeSamples[ti]), ti);
timeArray.set(MTime(pointsTimeSamples[ti] * timeSampleMultiplier, timeUnit), ti);
}

// Key/Animate the weights
Expand Down
21 changes: 13 additions & 8 deletions lib/mayaUsd/fileio/translators/translatorMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@
namespace MAYAUSD_NS_DEF {

TranslatorMeshRead::TranslatorMeshRead(
const UsdGeomMesh& mesh,
const UsdPrim& prim,
const MObject& transformObj,
const MObject& stageNode,
const GfInterval& frameRange,
bool wantCacheAnimation,
MStatus* status)
const UsdGeomMesh& mesh,
const UsdPrim& prim,
const MObject& transformObj,
const MObject& stageNode,
const GfInterval& frameRange,
bool wantCacheAnimation,
UsdMayaPrimReaderContext* context,
MStatus* status)
: m_wantCacheAnimation(wantCacheAnimation)
, m_pointsNumTimeSamples(0u)
{
Expand Down Expand Up @@ -298,11 +299,15 @@ TranslatorMeshRead::TranslatorMeshRead(
// Animate the weights so that mesh0 has a weight of 1 at frame 0, etc.
MFnAnimCurve animFn;

// Get the values needed to convert time to the current maya scenes framerate
MTime::Unit timeUnit = MTime::uiUnit();
double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0;

// Construct the time array to be used for all the keys
MTimeArray timeArray;
timeArray.setLength(m_pointsNumTimeSamples);
for (unsigned int ti = 0u; ti < m_pointsNumTimeSamples; ++ti) {
timeArray.set(MTime(pointsTimeSamples[ti]), ti);
timeArray.set(MTime(pointsTimeSamples[ti] * timeSampleMultiplier, timeUnit), ti);
}

// Key/Animate the weights
Expand Down
16 changes: 9 additions & 7 deletions lib/mayaUsd/fileio/translators/translatorMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include <mayaUsd/base/api.h>
#include <mayaUsd/fileio/primReaderRegistry.h>

#include <pxr/pxr.h>
#include <pxr/usd/usdGeom/mesh.h>
Expand All @@ -36,13 +37,14 @@ class MAYAUSD_CORE_PUBLIC TranslatorMeshRead
{
public:
TranslatorMeshRead(
const UsdGeomMesh& mesh,
const UsdPrim& prim,
const MObject& transformObj,
const MObject& stageNode,
const GfInterval& frameRange,
bool wantCacheAnimation,
MStatus* status = nullptr);
const UsdGeomMesh& mesh,
const UsdPrim& prim,
const MObject& transformObj,
const MObject& stageNode,
const GfInterval& frameRange,
bool wantCacheAnimation,
UsdMayaPrimReaderContext* context,
MStatus* status = nullptr);

~TranslatorMeshRead() = default;

Expand Down
6 changes: 4 additions & 2 deletions lib/mayaUsd/fileio/translators/translatorNurbsPatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,12 @@ bool UsdMayaTranslatorNurbsPatch::Read(
MFnAnimCurve animFn;

// Construct the time array to be used for all the keys
MTimeArray timeArray;
MTime::Unit timeUnit = MTime::uiUnit();
double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0;
MTimeArray timeArray;
timeArray.setLength(numTimeSamples);
for (unsigned int ti = 0; ti < numTimeSamples; ++ti) {
timeArray.set(MTime(pointsTimeSamples[ti]), ti);
timeArray.set(MTime(pointsTimeSamples[ti] * timeSampleMultiplier, timeUnit), ti);
}

// Key/Animate the weights
Expand Down
4 changes: 3 additions & 1 deletion lib/mayaUsd/fileio/translators/translatorPrim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ void UsdMayaTranslatorPrim::Read(
UsdMayaPrimReaderContext* context)
{
UsdGeomImageable primSchema(prim);
MTime::Unit timeUnit = MTime::uiUnit();
double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0;
if (!primSchema) {
TF_CODING_ERROR("Prim %s is not UsdGeomImageable.", prim.GetPath().GetText());
return;
Expand Down Expand Up @@ -81,7 +83,7 @@ void UsdMayaTranslatorPrim::Read(
MTimeArray timeArray;
timeArray.setLength(numTimeSamples);
for (unsigned int ti = 0; ti < numTimeSamples; ++ti) {
timeArray.set(MTime(visTimeSamples[ti]), ti);
timeArray.set(MTime(visTimeSamples[ti] * timeSampleMultiplier, timeUnit), ti);
}

// Add the keys
Expand Down
6 changes: 4 additions & 2 deletions lib/mayaUsd/fileio/translators/translatorSkel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,10 @@ bool _CopyAnimFromSkel(
_GetJointAnimTimeSamples(skelQuery, args, &usdTimes);
MTimeArray mayaTimes;
mayaTimes.setLength(usdTimes.size());
MTime::Unit timeUnit = MTime::uiUnit();
double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0;
for (size_t i = 0; i < usdTimes.size(); ++i) {
mayaTimes[i] = usdTimes[i];
mayaTimes[i] = MTime(usdTimes[i] * timeSampleMultiplier, timeUnit);
}

MStatus status;
Expand Down Expand Up @@ -622,7 +624,7 @@ bool UsdMayaTranslatorSkel::CreateJointHierarchy(
jointContainerPath = skelQuery.GetPrim().GetPath();
jointContainerIsSkeleton = true;

// Create a joint to represent thte Skeleton.
// Create a joint to represent the Skeleton.
if (!UsdMayaTranslatorUtil::CreateNode(
jointContainerPath,
_MayaTokens->jointType,
Expand Down
10 changes: 8 additions & 2 deletions lib/mayaUsd/fileio/translators/translatorXformable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ static bool _pushUSDXformOpToMayaXform(
const UsdMayaPrimReaderArgs& args,
const UsdMayaPrimReaderContext* context)
{
MTime::Unit timeUnit = MTime::uiUnit();
double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0;

std::vector<double> xValue;
std::vector<double> yValue;
std::vector<double> zValue;
Expand All @@ -230,7 +233,7 @@ static bool _pushUSDXformOpToMayaXform(
xValue[ti] = value[0];
yValue[ti] = value[1];
zValue[ti] = value[2];
timeArray.set(MTime(timeSamples[ti]), ti);
timeArray.set(MTime(timeSamples[ti] * timeSampleMultiplier, timeUnit), ti);
} else {
TF_RUNTIME_ERROR(
"Missing sampled data on xformOp: %s", xformop.GetName().GetText());
Expand Down Expand Up @@ -380,6 +383,9 @@ static bool _pushUSDXformToMayaXform(

std::vector<UsdTimeCode> timeCodes;
MTimeArray timeArray;
MTime::Unit timeUnit = MTime::uiUnit();

double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0;

if (!timeSamples.empty()) {
// Convert all the time samples to UsdTimeCodes.
Expand Down Expand Up @@ -481,7 +487,7 @@ static bool _pushUSDXformToMayaXform(
ShearYZVal[ti] = shear[2];

if (!timeCode.IsDefault()) {
timeArray.set(MTime(timeCode.GetValue()), ti);
timeArray.set(MTime(timeCode.GetValue() * timeSampleMultiplier, timeUnit), ti);
}
}

Expand Down
1 change: 1 addition & 0 deletions lib/usd/translators/meshReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ bool MayaUsdPrimReaderMesh::Read(UsdMayaPrimReaderContext* context)
stageNode,
_GetArgs().GetTimeInterval(),
_GetArgs().GetUseAsAnimationCache(),
context,
&status);
CHECK_MSTATUS_AND_RETURN(status, false);

Expand Down
Loading

0 comments on commit a9674ae

Please sign in to comment.