Vector4.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <common/Vector4.h>
00022 #include <common/Defines.h>
00023 
00024 // Some maths funnies taken from ODE
00025 #define _R(i,j) R[(i)*4+(j)]
00026 #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)])
00027 #define dDOT41(a,b) dDOTpq(a,b,4,1)
00028 #define dDOT(a,b)   dDOTpq(a,b,1,1)
00029 #define dMULTIPLYOP1_331(A,op,B,C) \
00030 do { \
00031   (A)[0] op dDOT41((B),(C)); \
00032   (A)[1] op dDOT41((B+1),(C)); \
00033   (A)[2] op dDOT41((B+2),(C)); \
00034 } while(0)
00035 #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
00036 
00037 static Vector4 nullVector;
00038 
00039 Vector4 &Vector4::getNullVector()
00040 {
00041         nullVector.zero();
00042         return nullVector;
00043 }
00044 
00045 void Vector4::setQuatFromAxisAndAngle(Vector &axis, float angle)
00046 {
00047         float l = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2];
00048         if (l > 0.0f) 
00049         {
00050                 angle *= 0.5f;
00051                 V[0] = cosf(angle);
00052                 l = sinf(angle) * ((1.0f/sqrtf(l)));
00053                 V[1] = axis[0] * l;
00054                 V[2] = axis[1] * l;
00055                 V[3] = axis[2] * l;
00056         }
00057         else 
00058         {
00059                 V[0] = 1.0f;
00060                 V[1] = 0.0f;
00061                 V[2] = 0.0f;
00062                 V[3] = 0.0f;
00063         }
00064 }
00065 
00066 // derived from equations in "An Introduction
00067 // to Physically Based Modeling: Rigid Body Simulation - 1: Unconstrained
00068 // Rigid Body Dynamics" by David Baraff, Robotics Institute, Carnegie Mellon
00069 // University, 1997.
00070 void Vector4::getRotationMatrix(float *R)
00071 {
00072         // q = (s,vx,vy,vz)
00073         float qq1 = 2*V[1]*V[1];
00074         float qq2 = 2*V[2]*V[2];
00075         float qq3 = 2*V[3]*V[3];
00076         _R(0,0) = 1 - qq2 - qq3;
00077         _R(0,1) = 2*(V[1]*V[2] - V[0]*V[3]);
00078         _R(0,2) = 2*(V[1]*V[3] + V[0]*V[2]);
00079         _R(0,3) = 0.0f;
00080         _R(1,0) = 2*(V[1]*V[2] + V[0]*V[3]);
00081         _R(1,1) = 1 - qq1 - qq3;
00082         _R(1,2) = 2*(V[2]*V[3] - V[0]*V[1]);
00083         _R(1,3) = 0.0f;
00084         _R(2,0) = 2*(V[1]*V[3] - V[0]*V[2]);
00085         _R(2,1) = 2*(V[2]*V[3] + V[0]*V[1]);
00086         _R(2,2) = 1 - qq1 - qq2;
00087         _R(2,3) = 0.0f;
00088 }
00089 
00090 void Vector4::getOpenGLRotationMatrix(float *rotMatrix)
00091 {
00092         static float matrix[12];
00093         getRotationMatrix(matrix);
00094 
00095         rotMatrix[0] = matrix[0];
00096         rotMatrix[1] = matrix[4];
00097         rotMatrix[2] = matrix[8];
00098         rotMatrix[4] = matrix[1];
00099         rotMatrix[5] = matrix[5];
00100         rotMatrix[6] = matrix[9];
00101         rotMatrix[8] = matrix[2];
00102         rotMatrix[9] = matrix[6];
00103         rotMatrix[10] = matrix[10];
00104         rotMatrix[3] = rotMatrix[7] = rotMatrix[11] = 0.0;
00105         rotMatrix[15] = 1.0;
00106         rotMatrix[12] = rotMatrix[13] = rotMatrix[14] = 0.0;    
00107 }
00108 
00109 void Vector4::Normalize()
00110 {
00111         float l = dDOT(V,V) + V[3] * V[3];
00112         if (l > 0) 
00113         {
00114                 l = 1.0f / sqrtf(l);
00115                 V[0] *= l;
00116                 V[1] *= l;
00117                 V[2] *= l;
00118                 V[3] *= l;
00119         }
00120         else 
00121         {
00122                 V[0] = 1;
00123                 V[1] = 0;
00124                 V[2] = 0;
00125                 V[3] = 0;
00126         }
00127 }
00128 
00129 void Vector4::getRelativeVector(Vector &r, Vector &p)
00130 {
00131         static float matrix[12];
00132         getRotationMatrix(matrix);
00133 
00134         float *result = r;
00135         float *position = p;
00136         dMULTIPLY1_331(result, matrix, position);
00137 }
00138 
00139 void Vector4::dDQfromW(Vector4 &dq, Vector &w, Vector4 &q)
00140 {
00141         dq[0] = 0.5f *(- w[0]*q[1] - w[1]*q[2] - w[2]*q[3]);
00142         dq[1] = 0.5f *(  w[0]*q[0] + w[1]*q[3] - w[2]*q[2]);
00143         dq[2] = 0.5f *(- w[0]*q[3] + w[1]*q[0] + w[2]*q[1]);
00144         dq[3] = 0.5f *(  w[0]*q[2] - w[1]*q[1] + w[2]*q[0]);
00145 }

Generated on Mon Feb 16 15:14:49 2009 for Scorched3D by  doxygen 1.5.3