ModelMaths.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 <3dsparse/ModelMaths.h>
00022 #include <common/Defines.h>
00023 #include <math.h>
00024 
00025 void ModelMaths::quaternionSlerp(float p[4], float q[4], float t, float qt[4])
00026 {
00027         int i;
00028         float omega, cosom, sinom, sclp, sclq;
00029 
00030         // decide if one of the quaternions is backwards
00031         float a = 0;
00032         float b = 0;
00033         for (i = 0; i < 4; i++) {
00034                 a += (p[i]-q[i])*(p[i]-q[i]);
00035                 b += (p[i]+q[i])*(p[i]+q[i]);
00036         }
00037         if (a > b) {
00038                 for (i = 0; i < 4; i++) {
00039                         q[i] = -q[i];
00040                 }
00041         }
00042 
00043         cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3];
00044 
00045         if ((1.0 + cosom) > 0.00000001) {
00046                 if ((1.0 - cosom) > 0.00000001) {
00047                         omega = (float) acos( cosom );
00048                         sinom = sinf( omega );
00049                         sclp = sinf( (1.0f - t)*omega) / sinom;
00050                         sclq = sinf( t*omega ) / sinom;
00051                 }
00052                 else {
00053                         sclp = 1.0f - t;
00054                         sclq = t;
00055                 }
00056                 for (i = 0; i < 4; i++) {
00057                         qt[i] = sclp * p[i] + sclq * q[i];
00058                 }
00059         }
00060         else {
00061                 qt[0] = -p[1];
00062                 qt[1] = p[0];
00063                 qt[2] = -p[3];
00064                 qt[3] = p[2];
00065                 const float Q_PI = 3.14f;
00066                 sclp = sinf( (1.0f - t) * 0.5f * Q_PI);
00067                 sclq = sinf( t * 0.5f * Q_PI);
00068                 for (i = 0; i < 3; i++) {
00069                         qt[i] = sclp * p[i] + sclq * qt[i];
00070                 }
00071         }
00072 }
00073 
00074 void ModelMaths::quaternionMatrix(float quaternion[4], float matrix[3][4])
00075 {
00076         matrix[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
00077         matrix[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
00078         matrix[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
00079 
00080         matrix[0][1] = 2.0f * quaternion[0] * quaternion[1] - 2.0f * quaternion[3] * quaternion[2];
00081         matrix[1][1] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[2] * quaternion[2];
00082         matrix[2][1] = 2.0f * quaternion[1] * quaternion[2] + 2.0f * quaternion[3] * quaternion[0];
00083 
00084         matrix[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
00085         matrix[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
00086         matrix[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
00087 }
00088 
00089 void ModelMaths::angleQuaternion(const Vector &angles, float quaternion[4])
00090 {
00091         float           angle;
00092         float           sr, sp, sy, cr, cp, cy;
00093 
00094         // FIXME: rescale the inputs to 1/2 angle
00095         angle = angles[2] * 0.5f;
00096         sy = sinf(angle);
00097         cy = cosf(angle);
00098         angle = angles[1] * 0.5f;
00099         sp = sinf(angle);
00100         cp = cosf(angle);
00101         angle = angles[0] * 0.5f;
00102         sr = sinf(angle);
00103         cr = cosf(angle);
00104 
00105         quaternion[0] = sr*cp*cy-cr*sp*sy; // X
00106         quaternion[1] = cr*sp*cy+sr*cp*sy; // Y
00107         quaternion[2] = cr*cp*sy-sr*sp*cy; // Z
00108         quaternion[3] = cr*cp*cy+sr*sp*sy; // W
00109 }
00110 
00111 void ModelMaths::angleMatrix(const Vector &angles, float matrix[3][4])
00112 {
00113         float           angle;
00114         float           sr, sp, sy, cr, cp, cy;
00115         
00116         angle = angles[2] * (PI*2 / 360);
00117         sy = sinf(angle);
00118         cy = cosf(angle);
00119         angle = angles[1] * (PI*2 / 360);
00120         sp = sinf(angle);
00121         cp = cosf(angle);
00122         angle = angles[0] * (PI*2 / 360);
00123         sr = sinf(angle);
00124         cr = cosf(angle);
00125 
00126         // matrix = (Z * Y) * X
00127         matrix[0][0] = cp*cy;
00128         matrix[1][0] = cp*sy;
00129         matrix[2][0] = -sp;
00130         matrix[0][1] = sr*sp*cy+cr*-sy;
00131         matrix[1][1] = sr*sp*sy+cr*cy;
00132         matrix[2][1] = sr*cp;
00133         matrix[0][2] = (cr*sp*cy+-sr*-sy);
00134         matrix[1][2] = (cr*sp*sy+-sr*cy);
00135         matrix[2][2] = cr*cp;
00136         matrix[0][3] = 0.0;
00137         matrix[1][3] = 0.0;
00138         matrix[2][3] = 0.0;
00139 }
00140 
00141 void ModelMaths::concatTransforms(const float in1[3][4], const float in2[3][4], float out[3][4])
00142 {
00143         out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
00144                                 in1[0][2] * in2[2][0];
00145         out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
00146                                 in1[0][2] * in2[2][1];
00147         out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
00148                                 in1[0][2] * in2[2][2];
00149         out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] +
00150                                 in1[0][2] * in2[2][3] + in1[0][3];
00151         out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
00152                                 in1[1][2] * in2[2][0];
00153         out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
00154                                 in1[1][2] * in2[2][1];
00155         out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
00156                                 in1[1][2] * in2[2][2];
00157         out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] +
00158                                 in1[1][2] * in2[2][3] + in1[1][3];
00159         out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
00160                                 in1[2][2] * in2[2][0];
00161         out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
00162                                 in1[2][2] * in2[2][1];
00163         out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
00164                                 in1[2][2] * in2[2][2];
00165         out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] +
00166                                 in1[2][2] * in2[2][3] + in1[2][3];
00167 }
00168 
00169 void ModelMaths::vectorIRotate(const Vector &in1, const float in2[3][4], Vector &out)
00170 {
00171         out[0] = in1[0]*in2[0][0] + in1[1]*in2[1][0] + in1[2]*in2[2][0];
00172         out[1] = in1[0]*in2[0][1] + in1[1]*in2[1][1] + in1[2]*in2[2][1];
00173         out[2] = in1[0]*in2[0][2] + in1[1]*in2[1][2] + in1[2]*in2[2][2];
00174 }

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