[4] | 1 | /********************************************************************************
|
---|
| 2 | * Volatile - Volume Visualization Software for SAGE
|
---|
| 3 | * Copyright (C) 2004 Electronic Visualization Laboratory,
|
---|
| 4 | * University of Illinois at Chicago
|
---|
| 5 | *
|
---|
| 6 | * All rights reserved.
|
---|
| 7 | *
|
---|
| 8 | * Redistribution and use in source and binary forms, with or without
|
---|
| 9 | * modification, are permitted provided that the following conditions are met:
|
---|
| 10 | *
|
---|
| 11 | * * Redistributions of source code must retain the above copyright
|
---|
| 12 | * notice, this list of conditions and the following disclaimer.
|
---|
| 13 | * * Redistributions in binary form must reproduce the above
|
---|
| 14 | * copyright notice, this list of conditions and the following disclaimer
|
---|
| 15 | * in the documentation and/or other materials provided with the distribution.
|
---|
| 16 | * * Neither the name of the University of Illinois at Chicago nor
|
---|
| 17 | * the names of its contributors may be used to endorse or promote
|
---|
| 18 | * products derived from this software without specific prior written permission.
|
---|
| 19 | *
|
---|
| 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
---|
| 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
---|
| 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
---|
| 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
---|
| 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
---|
| 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
---|
| 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
---|
| 27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
---|
| 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
---|
| 29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
---|
| 30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
| 31 | *
|
---|
| 32 | * Direct questions, comments etc about Volatile to www.evl.uic.edu/cavern/forum
|
---|
| 33 | *********************************************************************************/
|
---|
| 34 |
|
---|
| 35 | #ifndef __MatrixMath_defined
|
---|
| 36 | #define __MatrixMath_defined
|
---|
| 37 | #include "VectorMath.h"
|
---|
| 38 |
|
---|
| 39 | //BAD SHALINI...dont assume Opengl - do this by hand
|
---|
| 40 | inline void computeMatrix(float angle, float axis[],GLdouble* mat) {
|
---|
| 41 | // Have OpenGL compute the new transformation (simple but slow)
|
---|
| 42 | glPushMatrix();
|
---|
| 43 | glLoadIdentity();
|
---|
| 44 | glRotatef(angle, axis[0], axis[1], axis[2]);
|
---|
| 45 | glMultMatrixd((GLdouble *) mat);
|
---|
| 46 | glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble *) mat);
|
---|
| 47 | glPopMatrix();
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | inline void computeMatrix(float angle, float axis[],GLfloat* mat) {
|
---|
| 51 | // Have OpenGL compute the new transformation (simple but slow)
|
---|
| 52 | glPushMatrix();
|
---|
| 53 | glLoadIdentity();
|
---|
| 54 | glRotatef(angle, axis[0], axis[1], axis[2]);
|
---|
| 55 | glMultMatrixf((GLfloat *) mat);
|
---|
| 56 | glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) mat);
|
---|
| 57 | glPopMatrix();
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 |
|
---|
| 61 | // copy two matricies -----------------------------------
|
---|
| 62 | inline void matrixEqual(GLfloat me[16], GLfloat m[16])
|
---|
| 63 | {
|
---|
| 64 | for(int i=0; i< 16; ++i) me[i] = m[i];
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | inline void matrixEqual(GLdouble me[16], GLdouble m[16])
|
---|
| 68 | {
|
---|
| 69 | for(int i=0; i< 16; ++i) me[i] = m[i];
|
---|
| 70 | }
|
---|
| 71 |
|
---|
| 72 | // maxb = ma * mb --------------------------------------
|
---|
| 73 | inline void matrixMult( GLfloat maxb[16], GLfloat ma[16], GLfloat mb[16] )
|
---|
| 74 | {
|
---|
| 75 | maxb[0] = ma[0]*mb[0] + ma[4]*mb[1] + ma[8]*mb[2] + ma[12]*mb[3];
|
---|
| 76 | maxb[1] = ma[1]*mb[0] + ma[5]*mb[1] + ma[9]*mb[2] + ma[13]*mb[3];
|
---|
| 77 | maxb[2] = ma[2]*mb[0] + ma[6]*mb[1] + ma[10]*mb[2] + ma[14]*mb[3];
|
---|
| 78 | maxb[3] = ma[3]*mb[0] + ma[7]*mb[1] + ma[11]*mb[2] + ma[15]*mb[3];
|
---|
| 79 |
|
---|
| 80 | maxb[4] = ma[0]*mb[4] + ma[4]*mb[5] + ma[8]*mb[6] + ma[12]*mb[7];
|
---|
| 81 | maxb[5] = ma[1]*mb[4] + ma[5]*mb[5] + ma[9]*mb[6] + ma[13]*mb[7];
|
---|
| 82 | maxb[6] = ma[2]*mb[4] + ma[6]*mb[5] + ma[10]*mb[6] + ma[14]*mb[7];
|
---|
| 83 | maxb[7] = ma[3]*mb[4] + ma[7]*mb[5] + ma[11]*mb[6] + ma[15]*mb[7];
|
---|
| 84 |
|
---|
| 85 | maxb[8] = ma[0]*mb[8] + ma[4]*mb[9] + ma[8]*mb[10] + ma[12]*mb[11];
|
---|
| 86 | maxb[9] = ma[1]*mb[8] + ma[5]*mb[9] + ma[9]*mb[10] + ma[13]*mb[11];
|
---|
| 87 | maxb[10] = ma[2]*mb[8] + ma[6]*mb[9] + ma[10]*mb[10] + ma[14]*mb[11];
|
---|
| 88 | maxb[11] = ma[3]*mb[8] + ma[7]*mb[9] + ma[11]*mb[10] + ma[15]*mb[11];
|
---|
| 89 |
|
---|
| 90 | maxb[12] = ma[0]*mb[12] + ma[4]*mb[13] + ma[8]*mb[14] + ma[12]*mb[15];
|
---|
| 91 | maxb[13] = ma[1]*mb[12] + ma[5]*mb[13] + ma[9]*mb[14] + ma[13]*mb[15];
|
---|
| 92 | maxb[14] = ma[2]*mb[12] + ma[6]*mb[13] + ma[10]*mb[14] + ma[14]*mb[15];
|
---|
| 93 | maxb[15] = ma[3]*mb[12] + ma[7]*mb[13] + ma[11]*mb[14] + ma[15]*mb[15];
|
---|
| 94 | }
|
---|
| 95 |
|
---|
| 96 | inline void matrixMult( GLdouble maxb[16], GLdouble ma[16], GLdouble mb[16] )
|
---|
| 97 | {
|
---|
| 98 | maxb[0] = ma[0]*mb[0] + ma[4]*mb[1] + ma[8]*mb[2] + ma[12]*mb[3];
|
---|
| 99 | maxb[1] = ma[1]*mb[0] + ma[5]*mb[1] + ma[9]*mb[2] + ma[13]*mb[3];
|
---|
| 100 | maxb[2] = ma[2]*mb[0] + ma[6]*mb[1] + ma[10]*mb[2] + ma[14]*mb[3];
|
---|
| 101 | maxb[3] = ma[3]*mb[0] + ma[7]*mb[1] + ma[11]*mb[2] + ma[15]*mb[3];
|
---|
| 102 |
|
---|
| 103 | maxb[4] = ma[0]*mb[4] + ma[4]*mb[5] + ma[8]*mb[6] + ma[12]*mb[7];
|
---|
| 104 | maxb[5] = ma[1]*mb[4] + ma[5]*mb[5] + ma[9]*mb[6] + ma[13]*mb[7];
|
---|
| 105 | maxb[6] = ma[2]*mb[4] + ma[6]*mb[5] + ma[10]*mb[6] + ma[14]*mb[7];
|
---|
| 106 | maxb[7] = ma[3]*mb[4] + ma[7]*mb[5] + ma[11]*mb[6] + ma[15]*mb[7];
|
---|
| 107 |
|
---|
| 108 | maxb[8] = ma[0]*mb[8] + ma[4]*mb[9] + ma[8]*mb[10] + ma[12]*mb[11];
|
---|
| 109 | maxb[9] = ma[1]*mb[8] + ma[5]*mb[9] + ma[9]*mb[10] + ma[13]*mb[11];
|
---|
| 110 | maxb[10] = ma[2]*mb[8] + ma[6]*mb[9] + ma[10]*mb[10] + ma[14]*mb[11];
|
---|
| 111 | maxb[11] = ma[3]*mb[8] + ma[7]*mb[9] + ma[11]*mb[10] + ma[15]*mb[11];
|
---|
| 112 |
|
---|
| 113 | maxb[12] = ma[0]*mb[12] + ma[4]*mb[13] + ma[8]*mb[14] + ma[12]*mb[15];
|
---|
| 114 | maxb[13] = ma[1]*mb[12] + ma[5]*mb[13] + ma[9]*mb[14] + ma[13]*mb[15];
|
---|
| 115 | maxb[14] = ma[2]*mb[12] + ma[6]*mb[13] + ma[10]*mb[14] + ma[14]*mb[15];
|
---|
| 116 | maxb[15] = ma[3]*mb[12] + ma[7]*mb[13] + ma[11]*mb[14] + ma[15]*mb[15];
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | // compute the inverse of a matrix
|
---|
| 120 | // invm = m^(-1)
|
---|
| 121 | inline void inverseMatrix( GLfloat invm[16], GLfloat m[16] )
|
---|
| 122 | {
|
---|
| 123 | GLfloat det =
|
---|
| 124 | m[0]*m[5]*m[10]-
|
---|
| 125 | m[0]*m[6]*m[9]-
|
---|
| 126 | m[1]*m[4]*m[10]+
|
---|
| 127 | m[1]*m[6]*m[8]+
|
---|
| 128 | m[2]*m[4]*m[9]-
|
---|
| 129 | m[2]*m[5]*m[8];
|
---|
| 130 |
|
---|
| 131 | invm[0] = (m[5]*m[10]-m[6]*m[9])/det;
|
---|
| 132 | invm[1] = (-m[1]*m[10]+m[2]*m[9])/det;
|
---|
| 133 | invm[2] = (m[1]*m[6]-m[2]*m[5])/det;
|
---|
| 134 | invm[3] = 0.0;
|
---|
| 135 |
|
---|
| 136 | invm[4] = (-m[4]*m[10]+m[6]*m[8])/det;
|
---|
| 137 | invm[5] = (m[0]*m[10]-m[2]*m[8])/det;
|
---|
| 138 | invm[6] = (-m[0]*m[6]+m[2]*m[4])/det;
|
---|
| 139 | invm[7] = 0.0;
|
---|
| 140 |
|
---|
| 141 | invm[8] = (m[4]*m[9]-m[5]*m[8])/det;
|
---|
| 142 | invm[9] = (-m[0]*m[9]+m[1]*m[8])/det;
|
---|
| 143 | invm[10] = (m[0]*m[5]-m[1]*m[4])/det;
|
---|
| 144 | invm[11] = 0.0;
|
---|
| 145 |
|
---|
| 146 | invm[12] = (-m[4]*m[9]*m[14]+m[4]*m[13]*m[10]+
|
---|
| 147 | m[5]*m[8]*m[14]-m[5]*m[12]*m[10]-
|
---|
| 148 | m[6]*m[8]*m[13]+m[6]*m[12]*m[9])/det;
|
---|
| 149 | invm[13] = (m[0]*m[9]*m[14]-m[0]*m[13]*m[10]-
|
---|
| 150 | m[1]*m[8]*m[14]+m[1]*m[12]*m[10]+
|
---|
| 151 | m[2]*m[8]*m[13]-m[2]*m[12]*m[9])/det;
|
---|
| 152 | invm[14] = (-m[0]*m[5]*m[14]+m[0]*m[13]*m[6]+
|
---|
| 153 | m[1]*m[4]*m[14]-m[1]*m[12]*m[6]-
|
---|
| 154 | m[2]*m[4]*m[13]+m[2]*m[12]*m[5])/det;
|
---|
| 155 | invm[15] = 1.0;
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 | inline void inverseMatrix( GLdouble invm[16], GLdouble m[16] )
|
---|
| 159 | {
|
---|
| 160 | GLfloat det = (float)(
|
---|
| 161 | m[0]*m[5]*m[10]-
|
---|
| 162 | m[0]*m[6]*m[9]-
|
---|
| 163 | m[1]*m[4]*m[10]+
|
---|
| 164 | m[1]*m[6]*m[8]+
|
---|
| 165 | m[2]*m[4]*m[9]-
|
---|
| 166 | m[2]*m[5]*m[8]);
|
---|
| 167 |
|
---|
| 168 | invm[0] = (m[5]*m[10]-m[6]*m[9])/det;
|
---|
| 169 | invm[1] = (-m[1]*m[10]+m[2]*m[9])/det;
|
---|
| 170 | invm[2] = (m[1]*m[6]-m[2]*m[5])/det;
|
---|
| 171 | invm[3] = 0.0;
|
---|
| 172 |
|
---|
| 173 | invm[4] = (-m[4]*m[10]+m[6]*m[8])/det;
|
---|
| 174 | invm[5] = (m[0]*m[10]-m[2]*m[8])/det;
|
---|
| 175 | invm[6] = (-m[0]*m[6]+m[2]*m[4])/det;
|
---|
| 176 | invm[7] = 0.0;
|
---|
| 177 |
|
---|
| 178 | invm[8] = (m[4]*m[9]-m[5]*m[8])/det;
|
---|
| 179 | invm[9] = (-m[0]*m[9]+m[1]*m[8])/det;
|
---|
| 180 | invm[10] = (m[0]*m[5]-m[1]*m[4])/det;
|
---|
| 181 | invm[11] = 0.0;
|
---|
| 182 |
|
---|
| 183 | invm[12] = (-m[4]*m[9]*m[14]+m[4]*m[13]*m[10]+
|
---|
| 184 | m[5]*m[8]*m[14]-m[5]*m[12]*m[10]-
|
---|
| 185 | m[6]*m[8]*m[13]+m[6]*m[12]*m[9])/det;
|
---|
| 186 | invm[13] = (m[0]*m[9]*m[14]-m[0]*m[13]*m[10]-
|
---|
| 187 | m[1]*m[8]*m[14]+m[1]*m[12]*m[10]+
|
---|
| 188 | m[2]*m[8]*m[13]-m[2]*m[12]*m[9])/det;
|
---|
| 189 | invm[14] = (-m[0]*m[5]*m[14]+m[0]*m[13]*m[6]+
|
---|
| 190 | m[1]*m[4]*m[14]-m[1]*m[12]*m[6]-
|
---|
| 191 | m[2]*m[4]*m[13]+m[2]*m[12]*m[5])/det;
|
---|
| 192 | invm[15] = 1.0;
|
---|
| 193 | }
|
---|
| 194 |
|
---|
| 195 | //transpose a matrix
|
---|
| 196 | inline void transposeMatrix(GLfloat m[16])
|
---|
| 197 | {
|
---|
| 198 | GLfloat tmp;
|
---|
| 199 | tmp = m[1];
|
---|
| 200 | m[1] = m[4];
|
---|
| 201 | m[4] = tmp;
|
---|
| 202 | tmp = m[2];
|
---|
| 203 | m[2] = m[8];
|
---|
| 204 | m[8] = tmp;
|
---|
| 205 | tmp = m[3];
|
---|
| 206 | m[3] = m[12];
|
---|
| 207 | m[12] = tmp;
|
---|
| 208 | tmp = m[6];
|
---|
| 209 | m[6] = m[9];
|
---|
| 210 | m[9] = tmp;
|
---|
| 211 | tmp = m[7];
|
---|
| 212 | m[7] = m[13];
|
---|
| 213 | m[13] = tmp;
|
---|
| 214 | tmp = m[11];
|
---|
| 215 | m[11] = m[14];
|
---|
| 216 | m[14] = tmp;
|
---|
| 217 |
|
---|
| 218 | }
|
---|
| 219 |
|
---|
| 220 | inline void transposeMatrix(GLdouble m[16])
|
---|
| 221 | {
|
---|
| 222 | GLdouble tmp;
|
---|
| 223 | tmp = m[1];
|
---|
| 224 | m[1] = m[4];
|
---|
| 225 | m[4] = tmp;
|
---|
| 226 | tmp = m[2];
|
---|
| 227 | m[2] = m[8];
|
---|
| 228 | m[8] = tmp;
|
---|
| 229 | tmp = m[3];
|
---|
| 230 | m[3] = m[12];
|
---|
| 231 | m[12] = tmp;
|
---|
| 232 | tmp = m[6];
|
---|
| 233 | m[6] = m[9];
|
---|
| 234 | m[9] = tmp;
|
---|
| 235 | tmp = m[7];
|
---|
| 236 | m[7] = m[13];
|
---|
| 237 | m[13] = tmp;
|
---|
| 238 | tmp = m[11];
|
---|
| 239 | m[11] = m[14];
|
---|
| 240 | m[14] = tmp;
|
---|
| 241 |
|
---|
| 242 | }
|
---|
| 243 |
|
---|
| 244 | //angle and axis to a rotation matrix ----------------------------
|
---|
| 245 | inline void axis2Rot( GLfloat m[16], GLfloat k[3], GLfloat theta )
|
---|
| 246 | {
|
---|
| 247 | float c = (float)cos(theta);
|
---|
| 248 | float s = (float)sin(theta);
|
---|
| 249 | float v = 1 - c;
|
---|
| 250 |
|
---|
| 251 | m[0] = k[0]*k[0]*v + c;
|
---|
| 252 | m[4] = k[0]*k[1]*v - k[2]*s;
|
---|
| 253 | m[8] = k[0]*k[2]*v + k[1]*s;
|
---|
| 254 |
|
---|
| 255 | m[1] = k[0]*k[1]*v + k[2]*s;
|
---|
| 256 | m[5] = k[1]*k[1]*v + c;
|
---|
| 257 | m[9] = k[1]*k[2]*v - k[0]*s;
|
---|
| 258 |
|
---|
| 259 | m[2] = k[0]*k[2]*v - k[1]*s;
|
---|
| 260 | m[6] = k[1]*k[2]*v + k[0]*s;
|
---|
| 261 | m[10] = k[2]*k[2]*v + c;
|
---|
| 262 | }
|
---|
| 263 |
|
---|
| 264 | //angle and axis to a rotation matrix ----------------------------
|
---|
| 265 | inline void axis2Rot( GLdouble m[16], GLfloat k[3], GLfloat theta )
|
---|
| 266 | {
|
---|
| 267 | float c = (float)cos(theta);
|
---|
| 268 | float s = (float)sin(theta);
|
---|
| 269 | float v = 1 - c;
|
---|
| 270 |
|
---|
| 271 | m[0] = k[0]*k[0]*v + c;
|
---|
| 272 | m[4] = k[0]*k[1]*v - k[2]*s;
|
---|
| 273 | m[8] = k[0]*k[2]*v + k[1]*s;
|
---|
| 274 |
|
---|
| 275 | m[1] = k[0]*k[1]*v + k[2]*s;
|
---|
| 276 | m[5] = k[1]*k[1]*v + c;
|
---|
| 277 | m[9] = k[1]*k[2]*v - k[0]*s;
|
---|
| 278 |
|
---|
| 279 | m[2] = k[0]*k[2]*v - k[1]*s;
|
---|
| 280 | m[6] = k[1]*k[2]*v + k[0]*s;
|
---|
| 281 | m[10] = k[2]*k[2]*v + c;
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 |
|
---|
| 285 | inline void axis2Rot( GLdouble m[16], GLdouble k[3], GLdouble theta )
|
---|
| 286 | {
|
---|
| 287 | float c = (float)cos(theta);
|
---|
| 288 | float s = (float)sin(theta);
|
---|
| 289 | float v = 1 - c;
|
---|
| 290 |
|
---|
| 291 | m[0] = k[0]*k[0]*v + c;
|
---|
| 292 | m[4] = k[0]*k[1]*v - k[2]*s;
|
---|
| 293 | m[8] = k[0]*k[2]*v + k[1]*s;
|
---|
| 294 |
|
---|
| 295 | m[1] = k[0]*k[1]*v + k[2]*s;
|
---|
| 296 | m[5] = k[1]*k[1]*v + c;
|
---|
| 297 | m[9] = k[1]*k[2]*v - k[0]*s;
|
---|
| 298 |
|
---|
| 299 | m[2] = k[0]*k[2]*v - k[1]*s;
|
---|
| 300 | m[6] = k[1]*k[2]*v + k[0]*s;
|
---|
| 301 | m[10] = k[2]*k[2]*v + c;
|
---|
| 302 | }
|
---|
| 303 |
|
---|
| 304 | // Inverse angle-axis formula.-----------------------------------
|
---|
| 305 |
|
---|
| 306 | inline void rot2Axis( GLfloat k[3], GLfloat *theta, GLfloat m[16] )
|
---|
| 307 | {
|
---|
| 308 | GLfloat c = (float)(0.5 * (m[0] + m[5] + m[10] - 1.0));
|
---|
| 309 | GLfloat r1 = m[6] - m[9];
|
---|
| 310 | GLfloat r2 = m[8] - m[2];
|
---|
| 311 | GLfloat r3 = m[1] - m[4];
|
---|
| 312 | GLfloat s = (float)(0.5 * sqrt(r1*r1+r2*r2+r3*r3));
|
---|
| 313 |
|
---|
| 314 | *theta = (float)atan2(s, c);
|
---|
| 315 |
|
---|
| 316 | if( fabs(s) > EPSILON )
|
---|
| 317 | {
|
---|
| 318 | c = (float)(2.0*s);
|
---|
| 319 |
|
---|
| 320 | k[0] = r1 / c;
|
---|
| 321 | k[1] = r2 / c;
|
---|
| 322 | k[2] = r3 / c;
|
---|
| 323 | }
|
---|
| 324 | else
|
---|
| 325 | {
|
---|
| 326 | if( c > 0 ) // theta = 0
|
---|
| 327 | {
|
---|
| 328 | k[0] = 0;
|
---|
| 329 | k[1] = 0;
|
---|
| 330 | k[2] = 1;
|
---|
| 331 | }
|
---|
| 332 | else // theta = +-pi: Shepperd procedure
|
---|
| 333 | {
|
---|
| 334 | GLfloat k0_2 = (m[0] + 1)/2;
|
---|
| 335 | GLfloat k1_2 = (m[5] + 1)/2;
|
---|
| 336 | GLfloat k2_2 = (m[10] + 1)/2;
|
---|
| 337 |
|
---|
| 338 | if( k0_2 > k1_2 )
|
---|
| 339 | {
|
---|
| 340 | if( k0_2 > k2_2 ) // k0 biggest
|
---|
| 341 | {
|
---|
| 342 | k[0] = (float)sqrt(k1_2);
|
---|
| 343 | k[1] = (m[1] + m[4])/(4*k[0]);
|
---|
| 344 | k[2] = (m[2] + m[8])/(4*k[0]);
|
---|
| 345 | }
|
---|
| 346 | else // k2 biggest
|
---|
| 347 | {
|
---|
| 348 | k[2] = (float)sqrt(k2_2);
|
---|
| 349 | k[0] = (m[2] + m[8])/(4*k[2]);
|
---|
| 350 | k[1] = (m[6] + m[9])/(4*k[2]);
|
---|
| 351 | }
|
---|
| 352 | }
|
---|
| 353 | else
|
---|
| 354 | {
|
---|
| 355 | if( k1_2 > k2_2 ) // k1 biggest
|
---|
| 356 | {
|
---|
| 357 | k[1] = (float)sqrt(k1_2);
|
---|
| 358 | k[0] = (m[1] + m[4])/(4*k[1]);
|
---|
| 359 | k[2] = (m[6] + m[9])/(4*k[1]);
|
---|
| 360 | }
|
---|
| 361 | else // k2 biggest
|
---|
| 362 | {
|
---|
| 363 | k[2] = (float)sqrt(k2_2);
|
---|
| 364 | k[0] = (m[2] + m[8])/(4*k[2]);
|
---|
| 365 | k[1] = (m[6] + m[9])/(4*k[2]);
|
---|
| 366 | }
|
---|
| 367 | }
|
---|
| 368 | }
|
---|
| 369 | }
|
---|
| 370 | }
|
---|
| 371 |
|
---|
| 372 | //quaternion to rotation matrix
|
---|
| 373 |
|
---|
| 374 | inline void q2R( GLfloat m[16], GLfloat q[4] )
|
---|
| 375 | {
|
---|
| 376 | m[0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3];
|
---|
| 377 | m[1] = 2*q[1]*q[2] + 2*q[0]*q[3];
|
---|
| 378 | m[2] = 2*q[1]*q[3] - 2*q[0]*q[2];
|
---|
| 379 |
|
---|
| 380 | m[4] = 2*q[1]*q[2] - 2*q[0]*q[3];
|
---|
| 381 | m[5] = q[0]*q[0] + q[2]*q[2] - q[1]*q[1] - q[3]*q[3];
|
---|
| 382 | m[6] = 2*q[2]*q[3] + 2*q[0]*q[1];
|
---|
| 383 |
|
---|
| 384 | m[8] = 2*q[1]*q[3] + 2*q[0]*q[2];
|
---|
| 385 | m[9] = 2*q[2]*q[3] - 2*q[0]*q[1];
|
---|
| 386 | m[10]= q[0]*q[0] + q[3]*q[3] - q[1]*q[1] - q[2]*q[2];
|
---|
| 387 | }
|
---|
| 388 |
|
---|
| 389 | inline void axisToQuat(float a[3], float phi, float q[4])
|
---|
| 390 | {
|
---|
| 391 | vNormal(a);
|
---|
| 392 | vCopy(a,q);
|
---|
| 393 | vScale(q,(float)(sin(phi/2.0)));
|
---|
| 394 | q[3] = (float)(cos(phi/2.0));
|
---|
| 395 | }
|
---|
| 396 |
|
---|
| 397 | /////////////////////////////////////////////////////////////////////////////
|
---|
| 398 | //
|
---|
| 399 | // Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
|
---|
| 400 | // If they don't add up to 1.0, dividing by their magnitued will
|
---|
| 401 | // renormalize them.
|
---|
| 402 | //
|
---|
| 403 | // Note: See the following for more information on quaternions:
|
---|
| 404 | //
|
---|
| 405 | // - Shoemake, K., Animating rotation with quaternion curves, Computer
|
---|
| 406 | // Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
|
---|
| 407 | // - Pletinckx, D., Quaternion calculus as a basic tool in computer
|
---|
| 408 | // graphics, The Visual Computer 5, 2-13, 1989.
|
---|
| 409 | //
|
---|
| 410 | inline void normalizeQuat(float q[4])
|
---|
| 411 | {
|
---|
| 412 | float mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
|
---|
| 413 | for (int i = 0; i < 4; i++) q[i] /= mag;
|
---|
| 414 | }
|
---|
| 415 |
|
---|
| 416 | /////////////////////////////////////////////////////////////////////////////
|
---|
| 417 | //
|
---|
| 418 | // Given two rotations, e1 and e2, expressed as quaternion rotations,
|
---|
| 419 | // figure out the equivalent single rotation and stuff it into dest.
|
---|
| 420 | //
|
---|
| 421 | // This routine also normalizes the result every RENORMCOUNT times it is
|
---|
| 422 | // called, to keep error from creeping in.
|
---|
| 423 | //
|
---|
| 424 | // NOTE: This routine is written so that q1 or q2 may be the same
|
---|
| 425 | // as dest (or each other).
|
---|
| 426 | //
|
---|
| 427 | inline void addQuats(float q1[4], float q2[4], float dest[4])
|
---|
| 428 | {
|
---|
| 429 | static int count=0;
|
---|
| 430 | float t1[4], t2[4], t3[4];
|
---|
| 431 | float tf[4];
|
---|
| 432 |
|
---|
| 433 | vCopy(q1,t1);
|
---|
| 434 | vScale(t1,q2[3]);
|
---|
| 435 |
|
---|
| 436 | vCopy(q2,t2);
|
---|
| 437 | vScale(t2,q1[3]);
|
---|
| 438 |
|
---|
| 439 | vCross(q2,q1,t3);
|
---|
| 440 | vAdd(t1,t2,tf);
|
---|
| 441 | vAdd(t3,tf,tf);
|
---|
| 442 | tf[3] = q1[3] * q2[3] - vDot(q1,q2);
|
---|
| 443 |
|
---|
| 444 | dest[0] = tf[0];
|
---|
| 445 | dest[1] = tf[1];
|
---|
| 446 | dest[2] = tf[2];
|
---|
| 447 | dest[3] = tf[3];
|
---|
| 448 |
|
---|
| 449 | if (++count > 97) {
|
---|
| 450 | count = 0;
|
---|
| 451 | normalizeQuat(dest);
|
---|
| 452 | }
|
---|
| 453 | }
|
---|
| 454 |
|
---|
| 455 |
|
---|
| 456 |
|
---|
| 457 | /*
|
---|
| 458 | * Prints matrix to stderr.
|
---|
| 459 | */
|
---|
| 460 |
|
---|
| 461 | inline void printMatrix( GLfloat m[16] )
|
---|
| 462 | {
|
---|
| 463 | int i, j;
|
---|
| 464 |
|
---|
| 465 | for( i=0; i<4; i++ )
|
---|
| 466 | {
|
---|
| 467 | for( j=0; j<4; j++ )
|
---|
| 468 | fprintf(stderr, "%f ", m[i+j*4]);
|
---|
| 469 | fprintf(stderr, "\n");
|
---|
| 470 | }
|
---|
| 471 | fprintf(stderr, "\n");
|
---|
| 472 | }
|
---|
| 473 |
|
---|
| 474 | inline void printMatrix( GLdouble m[16] )
|
---|
| 475 | {
|
---|
| 476 | int i, j;
|
---|
| 477 |
|
---|
| 478 | for( i=0; i<4; i++ )
|
---|
| 479 | {
|
---|
| 480 | for( j=0; j<4; j++ )
|
---|
| 481 | fprintf(stderr, "%f ", m[i+j*4]);
|
---|
| 482 | fprintf(stderr, "\n");
|
---|
| 483 | }
|
---|
| 484 | fprintf(stderr, "\n");
|
---|
| 485 | }
|
---|
| 486 |
|
---|
| 487 | inline void buildLookAt(GLfloat m[16],
|
---|
| 488 | GLfloat eye[3], GLfloat at[3], GLfloat up[3])
|
---|
| 489 | {
|
---|
| 490 | //I am not 100% certain that my cross products are in the right order
|
---|
| 491 |
|
---|
| 492 | GLfloat tmp1[3], tmp2[3], tmp3[3];
|
---|
| 493 |
|
---|
| 494 | subV3(tmp1, eye, at);
|
---|
| 495 | GLfloat norm;
|
---|
| 496 | norm = normV3(tmp1);
|
---|
| 497 | tmp1[0] /=norm;
|
---|
| 498 | tmp1[1] /=norm;
|
---|
| 499 | tmp1[2] /=norm;
|
---|
| 500 |
|
---|
| 501 | m[2] =tmp1[0];
|
---|
| 502 | m[6] =tmp1[1];
|
---|
| 503 | m[10] =tmp1[2];
|
---|
| 504 |
|
---|
| 505 | crossV3(tmp2, up, tmp1);
|
---|
| 506 | norm = normV3(tmp2);
|
---|
| 507 | tmp2[0] /=norm;
|
---|
| 508 | tmp2[1] /=norm;
|
---|
| 509 | tmp2[2] /=norm;
|
---|
| 510 |
|
---|
| 511 | m[0] =tmp2[0];
|
---|
| 512 | m[4] =tmp2[1];
|
---|
| 513 | m[8] =tmp2[2];
|
---|
| 514 |
|
---|
| 515 | crossV3(tmp3, tmp1, tmp2);
|
---|
| 516 | norm = normV3(tmp3);
|
---|
| 517 | tmp3[0] /=norm;
|
---|
| 518 | tmp3[1] /=norm;
|
---|
| 519 | tmp3[2] /=norm;
|
---|
| 520 |
|
---|
| 521 | m[1] =tmp3[0];
|
---|
| 522 | m[5] =tmp3[1];
|
---|
| 523 | m[9] =tmp3[2];
|
---|
| 524 |
|
---|
| 525 | m[12]= -eye[0];
|
---|
| 526 | m[13]= -eye[1];
|
---|
| 527 | m[14]= -eye[2];
|
---|
| 528 | m[15]= 1;
|
---|
| 529 |
|
---|
| 530 | m[3] = 0;
|
---|
| 531 | m[7] = 0;
|
---|
| 532 | m[11] = 0;
|
---|
| 533 | }
|
---|
| 534 |
|
---|
| 535 | //give the original 8 vertices and the model view matrix
|
---|
| 536 | //This function returns true if the given point is within the bounds of these vertices
|
---|
| 537 | inline int withinBounds3D(GLdouble mv[16], float bbox[8][3], float point[3]) {
|
---|
| 538 | float min[3], max[3];
|
---|
| 539 | min[0] = min[1] = min[2] = 10;
|
---|
| 540 | max[0] = max[1] = max[2] = -10;
|
---|
| 541 | float rotatedbbox[8][3];
|
---|
| 542 | for(int i=0; i<8; ++i){
|
---|
| 543 | translateV3W(rotatedbbox[i], mv, bbox[i]); //get the rotated vol coords
|
---|
| 544 | //now get the max and min z in view space
|
---|
| 545 | if(max[2]< MAX(max[2], rotatedbbox[i][2])){
|
---|
| 546 | max[2] = MAX(max[2], rotatedbbox[i][2]);
|
---|
| 547 | }
|
---|
| 548 | if(min[2] > MIN(min[2], rotatedbbox[i][2])){
|
---|
| 549 | min[2] = MIN(min[2], rotatedbbox[i][2]);
|
---|
| 550 | }
|
---|
| 551 | //now get the max and min x in view space
|
---|
| 552 | if(max[0]< MAX(max[0], rotatedbbox[i][0])){
|
---|
| 553 | max[0] = MAX(max[0], rotatedbbox[i][0]);
|
---|
| 554 | }
|
---|
| 555 | if(min[0] > MIN(min[0], rotatedbbox[i][0])){
|
---|
| 556 | min[0] = MIN(min[0], rotatedbbox[i][0]);
|
---|
| 557 | }
|
---|
| 558 | //now get the max and min y in view space
|
---|
| 559 | if(max[1]< MAX(max[1], rotatedbbox[i][1])){
|
---|
| 560 | max[1] = MAX(max[1], rotatedbbox[i][1]);
|
---|
| 561 | }
|
---|
| 562 | if(min[1] > MIN(min[1], rotatedbbox[i][1])){
|
---|
| 563 | min[1] = MIN(min[1], rotatedbbox[i][1]);
|
---|
| 564 | }
|
---|
| 565 | }
|
---|
| 566 | if (point[0]>min[0] && point[0]<max[0]
|
---|
| 567 | && point[1]>min[1] && point[1]<max[1]) {
|
---|
| 568 | // && point[2]>min[2] && point[2]<max[2]) {
|
---|
| 569 | //pointer is within the bounds
|
---|
| 570 | return true;
|
---|
| 571 | }
|
---|
| 572 | else
|
---|
| 573 | return false;
|
---|
| 574 | }
|
---|
| 575 |
|
---|
| 576 | //give the original 4 vertices and the model view matrix
|
---|
| 577 | //This function returns true if the given point is within the bounds of these vertices
|
---|
| 578 | inline int withinBounds2D(GLdouble mv[16], float bbox[4][3], float point[3]) {
|
---|
| 579 | float min[3], max[3];
|
---|
| 580 | min[0] = min[1] = min[2] = 10;
|
---|
| 581 | max[0] = max[1] = max[2] = -10;
|
---|
| 582 | float rotatedbbox[4][3];
|
---|
| 583 | for(int i=0; i<4; ++i){
|
---|
| 584 | translateV3W(rotatedbbox[i], mv, bbox[i]); //get the rotated vol coords
|
---|
| 585 | //now get the max and min z in view space
|
---|
| 586 | if(max[2]< MAX(max[2], rotatedbbox[i][2])){
|
---|
| 587 | max[2] = MAX(max[2], rotatedbbox[i][2]);
|
---|
| 588 | }
|
---|
| 589 | if(min[2] > MIN(min[2], rotatedbbox[i][2])){
|
---|
| 590 | min[2] = MIN(min[2], rotatedbbox[i][2]);
|
---|
| 591 | }
|
---|
| 592 | //now get the max and min x in view space
|
---|
| 593 | if(max[0]< MAX(max[0], rotatedbbox[i][0])){
|
---|
| 594 | max[0] = MAX(max[0], rotatedbbox[i][0]);
|
---|
| 595 | }
|
---|
| 596 | if(min[0] > MIN(min[0], rotatedbbox[i][0])){
|
---|
| 597 | min[0] = MIN(min[0], rotatedbbox[i][0]);
|
---|
| 598 | }
|
---|
| 599 | //now get the max and min y in view space
|
---|
| 600 | if(max[1]< MAX(max[1], rotatedbbox[i][1])){
|
---|
| 601 | max[1] = MAX(max[1], rotatedbbox[i][1]);
|
---|
| 602 | }
|
---|
| 603 | if(min[1] > MIN(min[1], rotatedbbox[i][1])){
|
---|
| 604 | min[1] = MIN(min[1], rotatedbbox[i][1]);
|
---|
| 605 | }
|
---|
| 606 | }
|
---|
| 607 | if (point[0]>min[0] && point[0]<max[0]
|
---|
| 608 | && point[1]>min[1] && point[1]<max[1]) {
|
---|
| 609 | // && point[2]>min[2] && point[2]<max[2]) {
|
---|
| 610 | //pointer is within the bounds
|
---|
| 611 | return true;
|
---|
| 612 | }
|
---|
| 613 | else
|
---|
| 614 | return false;
|
---|
| 615 | }
|
---|
| 616 |
|
---|
| 617 |
|
---|
| 618 | #endif
|
---|