//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- 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; }