Пример #1
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void DrawableVectors::vectorMatrix(size_t vectorIndex, float vectorMatArray[16])
{
    const Vec3f& anchorPt = m_vertexArray->get(vectorIndex);
    Vec3f vec = m_vectorArray->get(vectorIndex);
    float length = vec.length();

    Quatf rotQuat;

    // This should really be a ratio eval based on length of vector
    // Copied from VTOVectorDrawer.cpp. TODO: refactor
    static const float TINY_VEC_COMP = 0.0000000001f;
    bool negZOnly = vec.z() < 0.0f && Math::abs(vec.x()) < TINY_VEC_COMP && Math::abs(vec.y()) < TINY_VEC_COMP;
    
    if (negZOnly) 
    {
        rotQuat.set(0.0f, 1.0f, 0.0f, 0.0f);
    }
    else
    {
        const Vec3f s = Vec3f::Z_AXIS;
        Vec3f d = vec/length;

        Vec3f v = s + d;
        Vec3f cross = v ^ d;
        float dot = v*d;

        rotQuat.set(cross.x(), cross.y(), cross.z(), dot);
    }

    float Nq = rotQuat.x()*rotQuat.x() + rotQuat.y()*rotQuat.y() + rotQuat.z()*rotQuat.z() + rotQuat.w()*rotQuat.w();
    float s = (Nq > 0.0f) ? (2.0f/Nq) : 0.0f;
    float xs = rotQuat.x()*s;	      
    float ys = rotQuat.y()*s;
    float zs = rotQuat.z()*s;
    float wx = rotQuat.w()*xs;
    float wy = rotQuat.w()*ys;
    float wz = rotQuat.w()*zs;
    float xx = rotQuat.x()*xs;
    float xy = rotQuat.x()*ys;
    float xz = rotQuat.x()*zs;
    float yy = rotQuat.y()*ys;
    float yz = rotQuat.y()*zs;
    float zz = rotQuat.z()*zs;

    vectorMatArray[0] = length*(1.0f - (yy + zz)); 
    vectorMatArray[1] = length*(xy + wz); 
    vectorMatArray[2] = length*(xz - wy);
    vectorMatArray[3] = 0.0f;

    vectorMatArray[4] = length*(xy - wz); 
    vectorMatArray[5] = length*(1.0f - (xx + zz)); 
    vectorMatArray[6] = length*(yz + wx);
    vectorMatArray[7] = 0.0f;

    vectorMatArray[8]  = length*(xz + wy); 
    vectorMatArray[9]  = length*(yz - wx); 
    vectorMatArray[10] = length*(1.0f - (xx + yy));
    vectorMatArray[11] = 0.0f;

    // Set the translation
    vectorMatArray[12] = anchorPt.x();
    vectorMatArray[13] = anchorPt.y();
    vectorMatArray[14] = anchorPt.z();
    vectorMatArray[15] = 1.0f;
}