当前位置: 首页>>代码示例>>C++>>正文


C++ Quaternion::AddScaledVector方法代码示例

本文整理汇总了C++中Quaternion::AddScaledVector方法的典型用法代码示例。如果您正苦于以下问题:C++ Quaternion::AddScaledVector方法的具体用法?C++ Quaternion::AddScaledVector怎么用?C++ Quaternion::AddScaledVector使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Quaternion的用法示例。


在下文中一共展示了Quaternion::AddScaledVector方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: ApplyPositionChange

void Contact::ApplyPositionChange(Vector3 linearChange[2], Vector3 angularChange[2], marb penetration) {
    const marb angularLimit = (marb)0.2f;
    marb angularMove[2];
    marb linearMove[2];

    marb totalInertia = 0;
    marb linearInertia[2];
    marb angularInertia[2];

    // We need to work out the inertia of each object in the direction
    // of the contact normal, due to angular inertia only.
    for (unsigned i = 0; i < 2; i++) if (body[i]) {
        Matrix3 inverseInertiaTensor;
        body[i]->GetInverseInertiaTensorWorld(&inverseInertiaTensor);

        // Use the same procedure as for calculating frictionless
        // velocity change to work out the angular inertia.
        Vector3 angularInertiaWorld =
            relativeContactPosition[i] % contactNormal;
        angularInertiaWorld =
            inverseInertiaTensor.Transform(angularInertiaWorld);
        angularInertiaWorld =
            angularInertiaWorld % relativeContactPosition[i];
        angularInertia[i] =
            angularInertiaWorld * contactNormal;

        // The linear component is simply the inverse mass
        linearInertia[i] = body[i]->GetInverseMass();

        // Keep track of the total inertia from all components
        totalInertia += linearInertia[i] + angularInertia[i];

        // We break the loop here so that the totalInertia value is
        // completely calculated (by both iterations) before
        // continuing.
    }

    // Loop through again calculating and applying the changes
    for (unsigned i = 0; i < 2; i++) if (body[i]) {
        // The linear and angular movements required are in proportion to
        // the two inverse inertias.
        marb sign = (i == 0)?1:-1;
        angularMove[i] =
            sign * penetration * (angularInertia[i] / totalInertia);
        linearMove[i] =
            sign * penetration * (linearInertia[i] / totalInertia);

        // To avoid angular projections that are too great (when mass is large
        // but inertia tensor is small) limit the angular move.
        Vector3 projection = relativeContactPosition[i];
        projection.AddScaledVector(
            contactNormal,
            -relativeContactPosition[i].ScalarProduct(contactNormal)
            );

        // Use the small angle approximation for the sine of the angle (i.e.
        // the magnitude would be sine(angularLimit) * projection.magnitude
        // but we approximate sine(angularLimit) to angularLimit).
        marb maxMagnitude = angularLimit * projection.Magnitude();

        if (angularMove[i] < -maxMagnitude) {
            marb totalMove = angularMove[i] + linearMove[i];
            angularMove[i] = -maxMagnitude;
            linearMove[i] = totalMove - angularMove[i];

        } else if (angularMove[i] > maxMagnitude) {
            marb totalMove = angularMove[i] + linearMove[i];
            angularMove[i] = maxMagnitude;
            linearMove[i] = totalMove - angularMove[i];
        }

        // We have the linear amount of movement required by turning
        // the rigid body (in angularMove[i]). We now need to
        // calculate the desired rotation to achieve that.
        if (angularMove[i] == 0) {
            // Easy case - no angular movement means no rotation.
            angularChange[i].Clear();

        } else {
            // Work out the direction we'd like to rotate in.
            Vector3 targetAngularDirection =
                relativeContactPosition[i].VectorProduct(contactNormal);

            Matrix3 inverseInertiaTensor;
            body[i]->GetInverseInertiaTensorWorld(&inverseInertiaTensor);

            // Work out the direction we'd need to rotate to achieve that
            angularChange[i] =
                inverseInertiaTensor.Transform(targetAngularDirection) *
                (angularMove[i] / angularInertia[i]);
        }

        // Velocity change is easier - it is just the linear movement
        // along the contact normal.
        linearChange[i] = contactNormal * linearMove[i];

        // Now we can start to apply the values we've calculated.
        // Apply the linear movement
        Vector3 pos;
        body[i]->GetPosition(&pos);
//.........这里部分代码省略.........
开发者ID:ChrisViqueira,项目名称:Marballs,代码行数:101,代码来源:contacts.cpp

示例2: ApplyPositionChange

void RigidBodyContact::ApplyPositionChange(Vector3* linearChange, Vector3* angularChange, float penetration)
{
    float angularLimit = 5.0f;
    float angularMove[2];
    float linearMove[2];
    float linearInertia[2];
    float angularInteria[2];
    float totalInertia = 0.0f;

    // Calculate the angular inertia using the same process as for calculating frictionless velocity change
    for (int i = 0; i < 2; i++)
    {
        if (Body[i] != NULL)
        {
            Matrix3x3 inverseInertiaTensor = Body[i]->GetInverseIntertiaTensorWorld();
            Vector3 angularInertiaWorld = m_relativeContactPosition[i].Cross(ContactNormal);
            angularInertiaWorld = angularInertiaWorld*inverseInertiaTensor; // TODO physics: is order correct here?
            angularInertiaWorld = angularInertiaWorld.Cross(m_relativeContactPosition[i]);
            angularInteria[i] = angularInertiaWorld.Dot(ContactNormal);

            // The linear inertia component is just the inverse mass
            linearInertia[i] = Body[i]->GetInverseMass();

            // Combine angular and linear to calculate total
            totalInertia += linearInertia[i] + angularInteria[i];
        }
    }

    // Calculate and apply changes
    for (int i = 0; i < 2; i++)
    {
        if (Body[i] != NULL)
        {
            // The linear and angular movements required are in proportion to the two inverse inertias
            float sign = (i == 0) ? 1.f : -1.f;
            angularMove[i] = sign * penetration * (angularInteria[i] / totalInertia);
            linearMove[i] = sign * penetration * (linearInertia[i] / totalInertia);

            // To avoid angular projections that are too great (when mass is large but inertia
            // tensor is small), limit the angular move
            Vector3 projection = m_relativeContactPosition[i];
            projection += ContactNormal * -m_relativeContactPosition[i].Dot(ContactNormal);

            // Use the small angle approximation for the sine of the angle (i.e. the magnitude would be
            // sin(angularLimit) * projection.magnitude, but we approximate sin(angularLimit) to angularLimit.
            float maxMagnitude = angularLimit * projection.Magnitude();

            if (angularMove[i] < -maxMagnitude)
            {
                float totalMove = angularMove[i] + linearMove[i];
                angularMove[i] = -maxMagnitude;
                linearMove[i] = totalMove - angularMove[i];
            }
            else if (angularMove[i] > maxMagnitude)
            {
                float totalMove = angularMove[i] + linearMove[i];
                angularMove[i] = maxMagnitude;
                linearMove[i] = totalMove - angularMove[i];
            }

            // We have the linear amount of movement required by turning the rigid body (angularMove[i]).
            // We now need to calculate the desired rotation to achieve that.
            if (Approximately(angularMove[i], 0.f))
            {
                // Easy case - no angular movement means no rotation.
                angularChange[i] = Vector3::Zero;
            }
            else
            {
                // Work out the direction we'd like to rotate in
                Vector3 targetAngularDirection = m_relativeContactPosition[i].Cross(ContactNormal);     // TODO physics: should this get normalized?

                // Work out the direction we'd need to rotate to achieve that
                Matrix3x3 inverseInertiaTensor = Body[i]->GetInverseIntertiaTensorWorld();
                angularChange[i] = (targetAngularDirection*inverseInertiaTensor)* (angularMove[i] / angularInteria[i]);      // TODO physics: is order correct here?
            }

            // Velocity change is just the linear movement along the contact normal
            linearChange[i] = ContactNormal * linearMove[i];

            // Apply the linear movement
            Vector3 pos = Body[i]->GetPosition();
            pos += linearMove[i] * ContactNormal;
            Body[i]->SetPosition(pos);

            // Apply the change in orientation
            Quaternion rot = Body[i]->GetRotation();
            rot.AddScaledVector(angularChange[i], 1.0);
            Body[i]->SetRotation(rot);

            // TODO calculate derived data for bodies that are not awake
        }
    }
}
开发者ID:gnleece,项目名称:Dogwood,代码行数:94,代码来源:RigidBodyContact.cpp


注:本文中的Quaternion::AddScaledVector方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。