[JIRA] Created: (SVC-5291) (vector / rotation) and (rotation / rotation) ambiguity in how the magnitude should be handled

Strife Onizuka (JIRA) no-reply at lindenlab.cascadeo.com
Mon Jan 18 22:34:32 PST 2010


(vector / rotation) and (rotation / rotation) ambiguity in how the magnitude should be handled
----------------------------------------------------------------------------------------------

                 Key: SVC-5291
                 URL: http://jira.secondlife.com/browse/SVC-5291
             Project: 2. Second Life Service - SVC
          Issue Type: Bug
          Components: Scripts
            Reporter: Strife Onizuka


When transforming rotations or vectors with another rotation (in the direction of the rotation) there is no ambiguity about how the magnitude of the output should be affected.
{code}
vector va;
rotation ra;
rotation b;

vector vc = va * b;
//llVecMag(vc) == llVecMag(va) * llRotDot(ra, ra)

rotation rc = ra * b;
//llRotMag(rc) = llRotMag(ra) * llRotMag(b)
{code}

Now depending upon how you define the "/" operator, it could produce two different affects.

If you define it as "transform 'a' in the opposite direction of 'b'" or as "do the inverse transformation of 'a' with 'b'" you could end up with these relationships:
{code}
vector va = <1,2,3>;
rotation ra = <0,0,0,1>;
rotation b = <0,0,0,1>;

vector vc = va / b;
//llVecMag(vc) == llVecMag(va) / llRotDot(ra, ra)

rotation rc = ra / b;
//llRotMag(rc) = llRotMag(ra) / llRotMag(b)
{code}

But that is not how LSL is implemented. "/" is defined as "Transform 'a' with the conjugate of 'b'"
{code}
vector va;
rotation ra;
rotation b;

vector vc = va / b;
//llVecMag(vc) == llVecMag(va) * llRotDot(ra, ra)

rotation rc = ra / b;
//llRotMag(rc) = llRotMag(ra) * llRotMag(b)
{code}

------

For these reason I do not think the "/" operator should be changed. However some new functions would be nice.
# Now changing this would probably break content.
# The possible gain in sanity is minimal if not illusionary.
# There is a small performance hit in doing this when compared to the current implementation and non-unit quaternions are an edge case.

I recommend two new functions:
{code}
vector llVecUnrot(vector v, rotation r) //const LLVector3& llVecUnrot(const LLVector3& v, const LLQuaternion& r)
{
    return v * r.reciprocal();
}

rotation llRotUnrot(rotation a, rotation b) //const LLQuaternion& llRotUnrot(const LLQuaternion& a, const LLQuaternion& b)
{
    return a * b.reciprocal();
}

const LLQuaternion& LLQuaternion::reciprocal()
{
        F32 reciprocal_of_magnitude_squared = 1.f / (mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ] + mQ[VS] * mQ[VS]);
        mQ[VX] *= -reciprocal_of_magnitude_squared;
        mQ[VY] *= -reciprocal_of_magnitude_squared;
        mQ[VZ] *= -reciprocal_of_magnitude_squared;
        mQ[VS] *= reciprocal_of_magnitude_squared;
        return (*this);
}
{code}
------

As you can see I've used some non-existent functions to aid in reporting this bug. We really do need llRotMag and llRotDot(Product) functions. Not to mention something like llRotScale(rotation rot, float multiplier) (since we can't multiply or divide rotation by floats/integers).
{code}
rotation llRotNorm(rotation rot) //const LLQuaternion& llRotMag(const LLQuaternion& rot)
{
    rot.normalize();
    return rot;
}

float llRotMag(rotation rot) //F32 llRotMag(const LLQuaternion& rot)
{
    return rot.magnitude();
}

float llRotDot(rotation a, rotation b) //F32 llRotDot(const LLQuaternion& a, const LLQuaternion& b)
{
    return dot(a, b);
}

//If you user doesn't need the Sqrt, why force it upon them?
float llRotMagSqrd(rotation rot) //F32 llRotMagSqrd(const LLQuaternion& rot)
{
    return rot.magnitude_squared();
}

rot llRotScale(rotation rot, float scale) //const LLQuaternion& llRotScale(const LLQuaternion& rot, F32 scale)
{
    return rot * scale;
}

//Many of the LLQuaternion functions would benefit from using these functions, as it would aid readability and reduce the amount of duplicate code.
inline F32 LLQuaternion::magnitude()
{
        return fsqrt(magnitude_squared());
}

inline F32 LLQuaternion::magnitude_squared()
{
        return mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ] + mQ[VS] * mQ[VS];
}
{code}

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.secondlife.com/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the Jira-notify mailing list