Skip to content

Commit

Permalink
Fixed transforms scale and rotation import issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomasch-unity3d committed Aug 17, 2017
1 parent 19ee51c commit cfb73c4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 99 deletions.
124 changes: 25 additions & 99 deletions Plugin/abci/Importer/aiXForm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,121 +20,47 @@ void aiXFormSample::updateConfig(const aiConfig &config, bool &topoChanged, bool
m_config = config;
}


inline abcV3 aiExtractTranslation(const AbcGeom::XformSample &sample, bool swapHandedness)
void aiXFormSample::decomposeXForm(const Imath::M44d &mat,Imath::V3d &scale,Imath::V3d &shear,Imath::Quatd &rotation,Imath::V3d &translation) const
{
abcV3 ret;

size_t n = sample.getNumOps();
size_t n_trans_op = 0;
for (size_t i = 0; i < n; ++i) {
const auto &op = sample.getOp(i);
if (op.getType() == AbcGeom::kTranslateOperation) {
if (++n_trans_op == 1) {
ret = op.getVector();
}
}
else if (op.getType() == AbcGeom::kMatrixOperation) {
n_trans_op = 2;
}
}

if (n_trans_op != 1) {
ret = sample.getTranslation();
}

if (swapHandedness)
{
ret.x *= -1.0f;
}
return ret;
}
Imath::M44d mat_remainder(mat);

// return rotation in quaternion
inline abcV4 aiExtractRotation(const AbcGeom::XformSample &sample, bool swapHandedness)
{
// XformSample store TRS as matrix, so XformSample::getAxis()/getAngle() may not match with original data.
// to workaround this problem, I try to extract rotation data from XformOp:
// enumerate XformOp and get rotation data if there is only one kRotateOperation.
// if this is not the case, fallback to XformSample::getAxis()/getAngle().

const float Deg2Rad = (aiPI / 180.0f);

abcV3 axis;
float angle;

size_t n = sample.getNumOps();
size_t n_rot_op = 0;
for (size_t i = 0; i < n; ++i) {
const auto &op = sample.getOp(i);
if (op.getType() == AbcGeom::kRotateOperation) {
if (++n_rot_op == 1) {
axis = op.getAxis();
angle = (float)op.getAngle()* Deg2Rad;
}
}
else if (op.getType() == AbcGeom::kMatrixOperation) {
n_rot_op = 2;
}
}
// Extract Scale, Shear
Imath::extractAndRemoveScalingAndShear(mat_remainder, scale, shear);

if (n_rot_op != 1) {
axis = sample.getAxis();
angle = (float)sample.getAngle()* Deg2Rad;
}
// Extract translation
translation.x = mat_remainder[3][0];
translation.y = mat_remainder[3][1];
translation.z = mat_remainder[3][2];

if (swapHandedness)
{
axis.x *= -1.0f;
angle *= -1.0f;
}

// axis/angle -> quaternion
float rs = std::sin(angle * 0.5f);
float rc = std::cos(angle * 0.5f);
return abcV4(axis.x*rs, axis.y*rs, axis.z*rs, rc);
}

inline abcV3 aiExtractScale(const AbcGeom::XformSample &sample)
{
abcV3 ret;

size_t n = sample.getNumOps();
size_t n_scale_op = 0;
for (size_t i = 0; i < n; ++i) {
const auto &op = sample.getOp(i);
if (op.getType() == AbcGeom::kScaleOperation) {
if (++n_scale_op == 1) {
ret = op.getVector();
}
}
else if (op.getType() == AbcGeom::kMatrixOperation) {
n_scale_op = 2;
}
}

if (n_scale_op != 1) {
ret = sample.getScale();
}
return ret;
// Extract rotation
rotation = extractQuat(mat_remainder);
}

void aiXFormSample::getData(aiXFormData &outData) const
{
DebugLog("aiXFormSample::getData()");

abcV3 trans = aiExtractTranslation(m_sample, m_config.swapHandedness);
abcV4 rot = aiExtractRotation(m_sample, m_config.swapHandedness);
abcV3 scale = aiExtractScale(m_sample);
Imath::V3d scale;
Imath::V3d shear;
Imath::Quatd rot;
abcV4 rotFinal;
Imath::V3d trans;
decomposeXForm(m_sample.getMatrix(), scale, shear, rot, trans);
if (m_config.swapHandedness)
{ trans.x *= -1.0f;
rotFinal = abcV4(-rot.v[0], rot.v[1], rot.v[2], -rot.r);
}
else
{
rotFinal = abcV4(rot.v[0], rot.v[1], rot.v[2], rot.r);
}

outData.inherits = m_sample.getInheritsXforms();
outData.translation = trans;
outData.rotation = rot;
outData.rotation = rotFinal;
outData.scale = scale;
}



aiXForm::aiXForm(aiObject *obj)
: super(obj)
{
Expand Down
2 changes: 2 additions & 0 deletions Plugin/abci/Importer/aiXForm.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ typedef aiSampleBase super;

public:
AbcGeom::XformSample m_sample;
private:
void decomposeXForm(const Imath::M44d &mat, Imath::V3d &scale, Imath::V3d &shear, Imath::Quatd &rotation, Imath::V3d &translation) const;
};


Expand Down

0 comments on commit cfb73c4

Please sign in to comment.