// ret abcV4(axis.x, axis.y, axis.z, angle) inline abcV4 aiExtractRotation(const AbcGeom::XformSample &sample, bool swapHandedness) { // XformSample は内部的にトランスフォームを行列で保持しており、getAxis(), getScale() などはその行列から値を復元しようとする。 // このため回転とスケールが同時にかかっている場合返ってくる値は正確ではなくなってしまう。 // これをなんとかするため、保持されている XformOp を見て kRotateOperation が 1 個だけあった場合はその axis angle を返し、 // それ以外の場合 getAxis() に fallback する。 const float Deg2Rad = (aiPI / 180.0f); abcV4 ret; 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) { abcV3 ax = op.getAxis(); ret = abcV4(ax.x, ax.y, ax.z, (float)op.getAngle() * Deg2Rad); } } else if (op.getType() == AbcGeom::kMatrixOperation) { n_rot_op = 2; } } if (n_rot_op != 1) { abcV3 ax = sample.getAxis(); ret = abcV4(ax.x, ax.y, ax.z, (float)sample.getAngle() * Deg2Rad); } if (swapHandedness) { ret.x *= -1.0f; ret.w *= -1.0f; } return ret; }
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); outData.inherits = m_sample.getInheritsXforms(); outData.translation = trans; outData.scale = scale; outData.rotation = abcV4(rot.x * std::sin(rot.w * 0.5f), rot.y * std::sin(rot.w * 0.5f), rot.z * std::sin(rot.w * 0.5f), std::cos(rot.w * 0.5f) ); }
void aiXform::cookSampleBody(Sample& sample) { auto& config = getConfig(); Imath::V3d scale; Imath::V3d shear; Imath::Quatd rot; Imath::V3d trans; decompose(sample.xf_sp.getMatrix(), scale, shear, rot, trans); if (config.interpolate_samples && m_current_time_offset != 0) { Imath::V3d scale2; Imath::Quatd rot2; Imath::V3d trans2; decompose(sample.xf_sp2.getMatrix(), scale2, shear, rot2, trans2); scale += (scale2 - scale)* m_current_time_offset; trans += (trans2 - trans)* m_current_time_offset; rot = Imath::slerpShortestArc(rot, rot2, (double)m_current_time_offset); } auto rot_final = abcV4( static_cast<float>(rot.v[0]), static_cast<float>(rot.v[1]), static_cast<float>(rot.v[2]), static_cast<float>(rot.r) ); if (config.swap_handedness) { trans.x *= -1.0f; rot_final.x = -rot_final.x; rot_final.w = -rot_final.w; } auto& dst = sample.data; dst.visibility = sample.visibility; dst.inherits = sample.xf_sp.getInheritsXforms(); dst.translation = trans; dst.rotation = rot_final; dst.scale = scale; }