00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 inline
00024 void build_basis(const Vector3 &u, Vector3 *v, Vector3 *w) {
00025 assert(u.IsUnitLength());
00026 assert(v && w);
00027
00028 const Real uz2 = u.m_z * u.m_z;
00029 Real norm = uz2 + u.m_y * u.m_y;
00030
00031 if(norm > EPS) {
00032 norm = sqrt(norm);
00033
00034
00035 v->m_x = 0.0;
00036 v->m_y = u.m_z / norm;
00037 v->m_z = -u.m_y / norm;
00038
00039
00040 w->m_x = u.m_y * v->m_z - v->m_y * u.m_z;
00041 w->m_y = -v->m_z * u.m_x;
00042 w->m_z = u.m_x * v->m_y;
00043 } else {
00044 norm = uz2 + u.m_x * u.m_x;
00045 assert(norm > EPS);
00046 norm = sqrt(norm);
00047
00048
00049 v->m_x = -u.m_z / norm;
00050 v->m_y = 0.0;
00051 v->m_z = u.m_x / norm;
00052
00053
00054 w->m_x = u.m_y * v->m_z;
00055 w->m_y = u.m_z * v->m_x - v->m_z * u.m_x;
00056 w->m_z = -v->m_x * u.m_y;
00057 }
00058
00059
00060 assert(v->IsUnitLength());
00061 assert(w->IsUnitLength());
00062
00063
00064 assert(fz(u * (*v)));
00065 assert(fz(u * (*w)));
00066 assert(fz((*v) * (*w)));
00067
00068
00069 assert(feq(u ^ (*v), *w));
00070 assert(feq((*v) ^ (*w), u));
00071 assert(feq((*w) ^ u, *v));
00072 }