Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 /* 00020 * Adapted from code with license: 00021 * 00022 * Copyright (c) 2002, Industrial Light & Magic, a division of Lucas 00023 * Digital Ltd. LLC. All rights reserved. 00024 * 00025 * Redistribution and use in source and binary forms, with or without 00026 * modification, are permitted provided that the following conditions are 00027 * met: 00028 * * Redistributions of source code must retain the above copyright 00029 * notice, this list of conditions and the following disclaimer. 00030 * * Redistributions in binary form must reproduce the above copyright 00031 * notice, this list of conditions and the following disclaimer in 00032 * the documentation and/or other materials provided with the 00033 * distribution. 00034 * * Neither the name of Industrial Light & Magic nor the names of its 00035 * contributors may be used to endorse or promote products derived 00036 * from this software without specific prior written permission. 00037 * 00038 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00039 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00040 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00041 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00042 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00043 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00044 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00045 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00046 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00047 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00048 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00049 */ 00050 00051 #include "util_math.h" 00052 #include "util_transform.h" 00053 00054 CCL_NAMESPACE_BEGIN 00055 00056 static bool transform_matrix4_gj_inverse(float R[][4], float M[][4]) 00057 { 00058 /* forward elimination */ 00059 for(int i = 0; i < 4; i++) { 00060 int pivot = i; 00061 float pivotsize = M[i][i]; 00062 00063 if(pivotsize < 0) 00064 pivotsize = -pivotsize; 00065 00066 for(int j = i + 1; j < 4; j++) { 00067 float tmp = M[j][i]; 00068 00069 if(tmp < 0) 00070 tmp = -tmp; 00071 00072 if(tmp > pivotsize) { 00073 pivot = j; 00074 pivotsize = tmp; 00075 } 00076 } 00077 00078 if(pivotsize == 0) 00079 return false; 00080 00081 if(pivot != i) { 00082 for(int j = 0; j < 4; j++) { 00083 float tmp; 00084 00085 tmp = M[i][j]; 00086 M[i][j] = M[pivot][j]; 00087 M[pivot][j] = tmp; 00088 00089 tmp = R[i][j]; 00090 R[i][j] = R[pivot][j]; 00091 R[pivot][j] = tmp; 00092 } 00093 } 00094 00095 for(int j = i + 1; j < 4; j++) { 00096 float f = M[j][i] / M[i][i]; 00097 00098 for(int k = 0; k < 4; k++) { 00099 M[j][k] -= f*M[i][k]; 00100 R[j][k] -= f*R[i][k]; 00101 } 00102 } 00103 } 00104 00105 /* backward substitution */ 00106 for(int i = 3; i >= 0; --i) { 00107 float f; 00108 00109 if((f = M[i][i]) == 0) 00110 return false; 00111 00112 for(int j = 0; j < 4; j++) { 00113 M[i][j] /= f; 00114 R[i][j] /= f; 00115 } 00116 00117 for(int j = 0; j < i; j++) { 00118 f = M[j][i]; 00119 00120 for(int k = 0; k < 4; k++) { 00121 M[j][k] -= f*M[i][k]; 00122 R[j][k] -= f*R[i][k]; 00123 } 00124 } 00125 } 00126 00127 return true; 00128 } 00129 00130 Transform transform_inverse(const Transform& tfm) 00131 { 00132 union { Transform T; float M[4][4]; } R, M; 00133 00134 R.T = transform_identity(); 00135 M.T = tfm; 00136 00137 if(!transform_matrix4_gj_inverse(R.M, M.M)) 00138 return transform_identity(); 00139 00140 return R.T; 00141 } 00142 00143 CCL_NAMESPACE_END 00144