Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/mathutil/rotate_to_src.cxx

Go to the documentation of this file.
00001 // Filename: rotate_to_src.cxx
00002 // Created by:  drose (04Nov99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 ////////////////////////////////////////////////////////////////////
00020 //     Function: _rotate_to
00021 //  Description: Computes the matrix necessary to rotate vector a onto
00022 //               vector b.  It is assumed that both vectors are
00023 //               normalized.
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   // Check for collinear vectors
00034   if (sin_theta < 0.0001) {
00035     // The vectors are collinear.
00036 
00037     if (cos_theta < 0.0f) {
00038       // The vectors are opposite; choose an arbitrary axis
00039       // perpendicular to a.
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     // The vectors are not collinear; determine the best axis.
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 

Generated on Fri May 2 00:40:31 2003 for Panda by doxygen1.3