Exemple #1
0
        long double pow_hex_mod(long double exponent, const long double modulus) {
            if (near_equal(modulus, 1.0L)) {
                return 0.0L;
            }

            long double accumulated(1.0L);
            long bin_exponent(next_bin_exponent(exponent));
            long double bin_power(bin_powers[bin_exponent]);
            while (bin_exponent >= 0L) {
                if (exponent >= bin_power) {
                    accumulated = SCROLLPI_MATH_FAST_FMOD_LONG(16.0L * accumulated, modulus);

                    // this subtraction is the secondary bottleneck of the bbp algorithm
                    exponent -= bin_power;
                }
                bin_power = bin_powers[--bin_exponent];
                if (bin_power >= 1.0L) {
                    // this fmod is the primary bottleneck of the bbp algorithm
                    accumulated = SCROLLPI_MATH_FAST_FMOD_LONG(accumulated * accumulated, modulus);
                }
            }
            return accumulated;
        }
void Xform::updateSample(Time t_)
{
    super::updateSample(t_);
    if (m_update_flag.bits == 0) {
        m_sample.flags = (m_sample.flags & ~(int)XformData::Flags::UpdatedMask);
        return;
    }
    if (m_update_flag.variant_set_changed) { m_summary_needs_update = true; }

    auto t = UsdTimeCode(t_);
    const auto& conf = getImportSettings();

    auto& sample = m_sample;
    auto prev = sample;

    if (m_summary.type == XformSummary::Type::TRS) {
        auto translate  = float3::zero();
        auto scale      = float3::one();
        auto rotation   = quatf::identity();

        for (auto& op : m_read_ops) {
            switch (op.GetOpType()) {
            case UsdGeomXformOp::TypeTranslate:
            {
                float3 tmp;
                op.GetAs((GfVec3f*)&tmp, t);
                translate += tmp;
                break;
            }
            case UsdGeomXformOp::TypeScale:
            {
                float3 tmp;
                op.GetAs((GfVec3f*)&tmp, t);
                scale *= tmp;
                break;
            }
            case UsdGeomXformOp::TypeOrient:
            {
                quatf tmp;
                op.GetAs((GfQuatf*)&tmp, t);
                rotation *= tmp;
                break;
            }
            case UsdGeomXformOp::TypeRotateX:
            {
                float angle;
                op.GetAs(&angle, t);
                rotation *= rotateX(angle * Deg2Rad);
                break;
            }
            case UsdGeomXformOp::TypeRotateY:
            {
                float angle;
                op.GetAs(&angle, t);
                rotation *= rotateY(angle * Deg2Rad);
                break;
            }
            case UsdGeomXformOp::TypeRotateZ:
            {
                float angle;
                op.GetAs(&angle, t);
                rotation *= rotateZ(angle * Deg2Rad);
                break;
            }
            case UsdGeomXformOp::TypeRotateXYZ: // 
            case UsdGeomXformOp::TypeRotateXZY: // 
            case UsdGeomXformOp::TypeRotateYXZ: // 
            case UsdGeomXformOp::TypeRotateYZX: // 
            case UsdGeomXformOp::TypeRotateZXY: // 
            case UsdGeomXformOp::TypeRotateZYX: // fall through
            {
                float3 euler;
                op.GetAs((GfVec3f*)&euler, t);
                rotation *= EulerToQuaternion(euler * Deg2Rad, op.GetOpType());
                break;
            }
            default:
                break;
            }
        }

        if (conf.swap_handedness) {
            translate.x *= -1.0f;
            rotation = swap_handedness(sample.rotation);
        }
        sample.position = translate;
        sample.rotation = rotation;
        sample.scale = scale;
    }
    else {
        GfMatrix4d result;
        result.SetIdentity();
        for (auto& op : m_read_ops) {
            auto m = op.GetOpTransform(t);
            result = m * result;
        }

        GfTransform gft;
        gft.SetMatrix(result);

        (GfMatrix4f&)sample.transform = GfMatrix4f(result);
        (GfVec3f&)sample.position = GfVec3f(gft.GetTranslation());
        (GfQuatf&)sample.rotation = GfQuatf(gft.GetRotation().GetQuat());
        (GfVec3f&)sample.scale = GfVec3f(gft.GetScale());
    }

    int update_flags = 0;
    if (!near_equal(prev.position, sample.position)) {
        update_flags |= (int)XformData::Flags::UpdatedPosition;
    }
    if (!near_equal(prev.rotation, sample.rotation)) {
        update_flags |= (int)XformData::Flags::UpdatedRotation;
    }
    if (!near_equal(prev.scale, sample.scale)) {
        update_flags |= (int)XformData::Flags::UpdatedScale;
    }
    sample.flags = (sample.flags & ~(int)XformData::Flags::UpdatedMask) | update_flags;
}