00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 static void
00026 _rotate_to(FLOATNAME(LMatrix3) &mat,
00027 const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) {
00028 FLOATTYPE cos_theta = a.dot(b);
00029
00030 FLOATNAME(LVector3) axis = a.cross(b);
00031 FLOATTYPE sin_theta = length(axis);
00032
00033
00034 if (sin_theta < 0.0001) {
00035
00036
00037 if (cos_theta < 0.0f) {
00038
00039
00040 FLOATNAME(LVector3) absa(fabs(a[0]), fabs(a[1]), fabs(a[2]));
00041 FLOATNAME(LVector3) lca(0., 0., 0.);
00042 lca[absa[0]<=absa[1] ? absa[0]<=absa[2] ? 0 : 2
00043 : absa[1]<=absa[2] ? 1 : 2] = 1.0f;
00044
00045 axis = normalize(a.cross(lca));
00046 } else {
00047 mat = FLOATNAME(LMatrix3)::ident_mat();
00048 return;
00049 }
00050
00051 } else {
00052
00053 axis /= sin_theta;
00054 }
00055
00056 FLOATTYPE x = axis[0];
00057 FLOATTYPE y = axis[1];
00058 FLOATTYPE z = axis[2];
00059
00060 FLOATTYPE t = 1.0f - cos_theta;
00061
00062 mat(0, 0) = t * x * x + cos_theta;
00063 mat(0, 1) = t * x * y + sin_theta * z;
00064 mat(0, 2) = t * x * z - sin_theta * y;
00065
00066 mat(1, 0) = t * y * x - sin_theta * z;
00067 mat(1, 1) = t * y * y + cos_theta;
00068 mat(1, 2) = t * y * z + sin_theta * x;
00069
00070 mat(2, 0) = t * z * x + sin_theta * y;
00071 mat(2, 1) = t * z * y - sin_theta * x;
00072 mat(2, 2) = t * z * z + cos_theta;
00073 }
00074
00075
00076 void
00077 rotate_to(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) {
00078 _rotate_to(mat, a, b);
00079 }
00080
00081 void
00082 rotate_to(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) {
00083 FLOATNAME(LMatrix3) m3;
00084 _rotate_to(m3, a, b);
00085 mat = FLOATNAME(LMatrix4)(m3);
00086 }
00087