[opengtl-commits] [238] * merge the C++ written in the OpenGTL library ( and make them C symbols)

[ Thread Index | Date Index | More lists.tuxfamily.org/opengtl-commits Archives ]


Revision: 238
Author:   cyrille
Date:     2008-06-26 22:12:48 +0200 (Thu, 26 Jun 2008)

Log Message:
-----------
* merge the C++ written in the OpenGTL library (and make them C symbols)
* add lookup3D functions
* add matrix/vector arithmetic operations

Modified Paths:
--------------
    trunk/OpenGTL/OpenCTL/CMakeLists.txt
    trunk/OpenGTL/OpenCTL/OpenCTL/CMakeLists.txt
    trunk/OpenGTL/OpenCTL/OpenCTL/compiler/Compiler.cpp

Added Paths:
-----------
    trunk/OpenGTL/OpenCTL/OpenCTL/StdLibFunctions.cpp
    trunk/OpenGTL/OpenCTL/OpenCTL/ctlstdlib.ctl

Removed Paths:
-------------
    trunk/OpenGTL/OpenCTL/CtlStdLib/


Modified: trunk/OpenGTL/OpenCTL/CMakeLists.txt
===================================================================
--- trunk/OpenGTL/OpenCTL/CMakeLists.txt	2008-06-26 20:09:43 UTC (rev 237)
+++ trunk/OpenGTL/OpenCTL/CMakeLists.txt	2008-06-26 20:12:48 UTC (rev 238)
@@ -10,7 +10,6 @@
 set(OPENCTL_LIB_SOVERSION ${OPENGTL_LIB_SOVERSION})
 
 add_subdirectory(OpenCTL)
-add_subdirectory(CtlStdLib)
 add_subdirectory(tools)
 
 # After tool to get CTLC variable

Modified: trunk/OpenGTL/OpenCTL/OpenCTL/CMakeLists.txt
===================================================================
--- trunk/OpenGTL/OpenCTL/OpenCTL/CMakeLists.txt	2008-06-26 20:09:43 UTC (rev 237)
+++ trunk/OpenGTL/OpenCTL/OpenCTL/CMakeLists.txt	2008-06-26 20:12:48 UTC (rev 238)
@@ -8,6 +8,7 @@
   ModulesManager.cpp
   Program.cpp
 # Internal files
+  StdLibFunctions.cpp
   compiler/Compiler.cpp
   compiler/LexerNG.cpp
   compiler/ParserNG.cpp
@@ -22,14 +23,10 @@
 add_definitions( -DCOUMPONENT_NAME=\"\\\"OpenCTL\\\"\" )
 
 if (NOT APPLE)
-  add_definitions( -D_OPENCTL_CTL_STD_LIB_BUILD_DIR_=\\"${CMAKE_CURRENT_BINARY_DIR}/../CtlStdLib/\\")
-  add_definitions( -D_OPENCTL_LIB_INSTALL_=\\"${CMAKE_INSTALL_PREFIX}/lib/\\")
-  add_definitions( -D_OPENCTL_CTL_STD_LIB_SRC_DIR_=\\"${CMAKE_CURRENT_SOURCE_DIR}/../CtlStdLib/\\")
+  add_definitions( -D_OPENCTL_CTL_STD_LIB_SRC_DIR_=\\"${CMAKE_CURRENT_SOURCE_DIR}/\\")
   add_definitions( -D_OPENCTL_CTL_SHARE_DIR_=\\"${SHARE_INSTALL_DIR}/ctl\\" )
 else (NOT APPLE)
-  add_definitions( -D_OPENCTL_CTL_STD_LIB_BUILD_DIR_='\"${CMAKE_CURRENT_BINARY_DIR}/../CtlStdLib/\"')
-  add_definitions( -D_OPENCTL_LIB_INSTALL_='\"${CMAKE_INSTALL_PREFIX}/lib/\"')
-  add_definitions( -D_OPENCTL_CTL_STD_LIB_SRC_DIR_='\"${CMAKE_CURRENT_SOURCE_DIR}/../CtlStdLib/\"')
+  add_definitions( -D_OPENCTL_CTL_STD_LIB_SRC_DIR_='\"${CMAKE_CURRENT_SOURCE_DIR}/\"')
   add_definitions( -D_OPENCTL_CTL_SHARE_DIR_='\"${SHARE_INSTALL_DIR}/ctl\"' )
 endif(NOT APPLE)
 
@@ -45,3 +42,5 @@
 configure_file("OpenCTL.pc.cmake" "${CMAKE_CURRENT_BINARY_DIR}/OpenCTL.pc" @ONLY)
 
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCTL.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)  
+
+install(FILES ctlstdlib.ctl DESTINATION ${SHARE_INSTALL_DIR}/ctl )

Copied: trunk/OpenGTL/OpenCTL/OpenCTL/StdLibFunctions.cpp (from rev 183, trunk/OpenGTL/OpenCTL/CtlStdLib/Print.cpp)
===================================================================
--- trunk/OpenGTL/OpenCTL/OpenCTL/StdLibFunctions.cpp	                        (rev 0)
+++ trunk/OpenGTL/OpenCTL/OpenCTL/StdLibFunctions.cpp	2008-06-26 20:12:48 UTC (rev 238)
@@ -0,0 +1,93 @@
+/*
+ *  Copyright (c) 2008 Cyrille Berger <cberger@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "GTLCore/String.h"
+
+#include <iostream>
+#include <cstdarg>
+
+#undef assert
+
+extern "C" {
+
+void assert( bool test)
+{
+  if(not test)
+  {
+    throw GTLCore::String("Assert");
+  }
+}
+
+bool isnan_f (float x)
+{
+  union {float f; unsigned int i;} u;
+  u.f = x;
+  return u.i == 0x7fffffff;
+}
+bool isnan_h (float x)
+{
+  union {float f; unsigned int i;} u;
+  u.f = x;
+  return u.i == 0x7fffffff;
+}
+
+
+void print(int nb, ...)
+{
+//   std::cout << nb << " : ";
+  va_list argp;
+  va_start(argp, nb);
+  for( int i = 0; i < nb; ++i)
+  {
+    int type = va_arg(argp, int);
+//     std::cout << type << " ";
+    switch(type)
+    {
+      case 0:
+      {
+        std::cout << va_arg(argp, int) << " ";
+      }
+        break;
+      case 1:
+      {
+        std::cout << va_arg(argp, double) << " ";
+      }
+        break;
+      case 2:
+      {
+        if( va_arg(argp, int))
+          std::cout << "true ";
+        else
+          std::cout << "false ";
+      }
+        break;
+      case 3:
+      {
+        std::cout << va_arg(argp, char*) << " ";
+        break;
+      }
+      default:
+        std::cout << "Unknown type (" << type << ")";
+    }
+  }
+  std::cout << std::endl;
+  va_end(argp);
+}
+
+}

Modified: trunk/OpenGTL/OpenCTL/OpenCTL/compiler/Compiler.cpp
===================================================================
--- trunk/OpenGTL/OpenCTL/OpenCTL/compiler/Compiler.cpp	2008-06-26 20:09:43 UTC (rev 237)
+++ trunk/OpenGTL/OpenCTL/OpenCTL/compiler/Compiler.cpp	2008-06-26 20:12:48 UTC (rev 238)
@@ -132,37 +132,6 @@
   d->errorMessage = "";
   setModuleName( moduleName );
   
-  // Load the standard library
-  GTLCore::String Error;
-  bool notLoaded;
-  if((notLoaded = llvm::sys::DynamicLibrary::LoadLibraryPermanently("libctlstdlib.so", &Error))) {
-    OCTL_DEBUG( "Error opening 'libctlstdlib.so': " << Error );
-    appendError( GTLCore::ErrorMessage(Error));
-  }
-#ifdef _OPENCTL_CTL_STD_LIB_BUILD_DIR_
-  if( notLoaded)
-  {
-    if((notLoaded = llvm::sys::DynamicLibrary::LoadLibraryPermanently((GTLCore::String(_OPENCTL_CTL_STD_LIB_BUILD_DIR_) + "libctlstdlib.so").c_str(), &Error))) {
-      OCTL_DEBUG( "Error opening 'libctlstdlib.so': " << Error );
-      appendError( GTLCore::ErrorMessage(Error));
-    }
-  }
-#endif
-#ifdef _OPENCTL_CTL_STD_LIB_BUILD_DIR_
-  if(notLoaded)
-  {
-    if((notLoaded = llvm::sys::DynamicLibrary::LoadLibraryPermanently((GTLCore::String(_OPENCTL_LIB_INSTALL_) + "libctlstdlib.so").c_str(), &Error))) {
-      OCTL_DEBUG( "Error opening 'libctlstdlib.so': " << Error );
-      appendError( GTLCore::ErrorMessage(Error));
-    }
-  }
-#endif
-  
-  if( notLoaded )
-  {
-    return 0;
-  }
-  
   // Create LLVM module
   d->module = moduleData->llvmModule();
   d->moduleData = moduleData;
@@ -170,8 +139,9 @@
 
   // Create Standard Library functions
   // CtlStdLib functions (except print which get a special treatement)
-  createStdLibFunction( "assert", "_Z6assertb", GTLCore::Type::Void, 1, GTLCore::Type::Boolean);
-  createStdLibFunction( "isnan_f", "_Z7isnan_ff", GTLCore::Type::Boolean, 1, GTLCore::Type::Float);
+  createStdLibFunction( "assert", "assert", GTLCore::Type::Void, 1, GTLCore::Type::Boolean);
+  createStdLibFunction( "isnan_f", "isnan_f", GTLCore::Type::Boolean, 1, GTLCore::Type::Float);
+  createStdLibFunction( "isnan_h", "isnan_h", GTLCore::Type::Boolean, 1, GTLCore::Type::Float);
   // C Math functions
   createStdLibFunction( "acos", "acosf", GTLCore::Type::Float, 1, GTLCore::Type::Float);
   createStdLibFunction( "asin", "asinf", GTLCore::Type::Float, 1, GTLCore::Type::Float);

Copied: trunk/OpenGTL/OpenCTL/OpenCTL/ctlstdlib.ctl (from rev 226, trunk/OpenGTL/OpenCTL/CtlStdLib/ctlstdlib.ctl)
===================================================================
--- trunk/OpenGTL/OpenCTL/OpenCTL/ctlstdlib.ctl	                        (rev 0)
+++ trunk/OpenGTL/OpenCTL/OpenCTL/ctlstdlib.ctl	2008-06-26 20:12:48 UTC (rev 238)
@@ -0,0 +1,694 @@
+/*
+ *  Copyright (c) 2008 Cyrille Berger <cberger@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// Float operation
+
+bool isfinite_f (float x)
+{
+  return x != FLT_POS_INF && x != FLT_NEG_INF && x != FLT_NAN;
+}
+
+bool isfinite_h (half x)
+{
+  return x != HALF_POS_INF && x != HALF_NEG_INF && x != HALF_NAN;
+}
+
+bool isnormal_f (float x)
+{
+  return isfinite_f(x) && x != 0.0;
+}
+bool isnormal_h (half x)
+{
+  return isfinite_h(x) && x != 0.0;
+}
+
+bool isinf_f (float x)
+{
+  return x == FLT_POS_INF || x == FLT_NEG_INF;
+}
+bool isinf_h (half x)
+{
+  return x == HALF_POS_INF || x != HALF_NEG_INF;
+}
+
+float pow10(float x)
+{
+  return pow(10,x);
+}
+
+half pow10_h(float x)
+{
+  return pow(10,x);
+}
+
+float hypot(float x, float y)
+{
+  return sqrt(x*x + y*y);
+}
+
+// misc mathematic function
+
+float min( float f1, float f2) // WARNING not mentioned in the Spec !
+{
+  if( f1 < f2)
+  {
+    return f1;
+  } else {
+    return f2;
+  }
+}
+
+float max( float f1, float f2) // WARNING not mentioned in the Spec !
+{
+  if( f1 > f2)
+  {
+    return f1;
+  } else {
+    return f2;
+  }
+}
+
+// lookup
+
+float lookup1D(float table[], float pMin, float pMax, float p)
+{
+  if( p < pMin ) return table[ 0 ];
+  if( p > pMax ) return table[ table.size - 1 ];
+  float t = (p - pMin) / (pMax - pMin ) * (table.size - 1 );
+  int i = floor( t );
+  float s = t - i;
+  return table[i] * ( 1 - s ) + table[i+1] * s; 
+}
+
+float lookupCubic1D (float table[], float pMin, float pMax, float p)
+{
+  if( p < pMin ) return table[ 0 ];
+  if( p > pMax ) return table[ table.size - 1 ];
+  
+  float t = (p - pMin) / (pMax - pMin) * (table.size-1);
+  int i = floor (t);
+  float s = t - i;
+  float m0;
+  float m1;
+  if( i > 0 )
+  {
+    m0 = (table[i+1] - table[i-1]) / 2;
+  }
+  if( i < table.size-2 )
+  {
+    m1 = (table[i+2] - table[i]) / 2;
+  }
+  if( i == 0) {
+    m0 = (3 * table[i+1] - table[i] - m1);
+  }
+  if( i == table.size-2 )
+  {
+    m1 = (3 * table[i+1] - table[i] - m0);
+  }
+  return table[i] * (2 * s*s*s - 3 * s*s + 1) + m0 * (s*s*s - 2 * s*s + s) + table[i+1] * (-2 * s*s*s + 3 * s*s) + m1 * (s*s*s - s*s);
+}
+
+float interpolate1D (float table[][2], float p)
+{
+  if( p < table[0][0] ) return table[0][1];
+  if( p > table[table.size-1][0] ) return table[table.size-1][1];
+  
+  for( int i = 0; i < table.size - 1; ++i )
+  {
+    if( table[i][0] <= p && p < table[i+1][0] )
+    {
+      float s = (p - table[i][0]) / (table[i+1][0] - table[i][0]);
+      return table[i][1] * ( 1 - s ) + table[i+1][1] * s;
+    }
+  }
+  return 0.0;
+}
+
+float interpolateCubic1D (float table[][2], float p)
+{
+  if( p < table[0][0] ) return table[0][1];
+  if( p > table[table.size-1][0] ) return table[table.size-1][1];
+  
+  for( int i = 0; i < table.size - 1; ++i )
+  {
+    if( table[i][0] <= p && p < table[i+1][0] )
+    {
+      float s = (p - table[i][0]) / (table[i+1][0] - table[i][0]);
+      float dx0 = (table[i][0] - table[i-1][0]);
+      float dx1 = (table[i+1][0] - table[i][0]);
+      float dx2 = (table[i+2][0] - table[i+1][0]);
+      float dy0 = (table[i][1] - table[i-1][1]);
+      float dy1 = (table[i+1][1] - table[i][1]);
+      float dy2 = (table[i+2][1] - table[i+1][1]);
+      
+      float m0;
+      float m1;
+      if( i > 0 )
+      {
+        m0 = (dy1 + dx1 * dy0 / dx0) / 2;
+      }
+      if( i < table.size-2 )
+      {
+        m1 = (dy1 + dx1 * dy2 / dx2) / 2;
+      }
+      if( i == 0) {
+        m0 = (3 * dy1 - m1) / 2;
+      }
+      if( i == table.size-2 )
+      {
+        m1 = (3 * dy1 - m0) / 2;
+      }
+      return table[i][1] * (2 * s*s*s - 3 * s*s + 1) +
+          m0 * (s*s*s - 2 * s*s + s) +
+          table[i+1][1] * (-2 * s*s*s + 3 * s*s) +
+          m1 * (s*s*s - s*s);
+    }
+  }
+  return 0.0;
+}
+
+float[3] lookup3D_f3
+         (float table[][][][3],
+          float pMin[3],
+          float pMax[3],
+          float p[3])
+{
+  float result[3];
+  int iMax = table.size - 1;
+  int jMax = table[0].size - 1;
+  int kMax = table[0][0].size - 1;
+  float q[3];
+  q[0] = max (pMin[0], min (pMax[0], p[0]));
+  q[1] = max (pMin[1], min (pMax[1], p[1]));
+  q[2] = max (pMin[2], min (pMax[2], p[2]));
+  
+  float ti = (p[0] - pMin[0]) / (pMax[0] - pMin[0]) * iMax;
+  int i = floor (ti);
+  float si = ti - i;
+  float tj = (p[1] - pMin[1]) / (pMax[1] - pMin[1]) * jMax;
+  int j = floor (tj);
+  float sj = tj - j;
+  float tk = (p[2] - pMin[2]) / (pMax[2] - pMin[2]) * kMax;
+  int k = floor (tk);
+  float sk = tk - k;
+  
+  for( int l = 0; l < 3; ++l)
+  {
+    result[ l ] = ((table[i][j][k][l] * (1-si) + table[i+1][j][k][l] * si) * (1-sj)
+                + (table[i][j+1][k][l] * (1-si) + table[i+1][j+1][k][l] * si) * sj ) * (1-sk)
+                + ((table[i][j][k+1][l] * (1-si) + table[i+1][j][k+1][l] * si) * (1-sj)
+                + (table[i][j+1][k+1][l] * (1-si) + table[i+1][j+1][k+1][l] * si) * sj ) * sk;
+  }
+  
+  return result;
+}
+
+void lookup3D_f
+       (float table[][][][3],
+        float pMin[3],
+        float pMax[3],
+        float p0, float p1, float p2,
+        output float q0, output float q1, output float q2)
+{
+  float p[3];
+  p[0] = p0;
+  p[1] = p1;
+  p[2] = p2;
+  float result[3] = lookup3D_f3( table, pMin, pMax, p );
+  q0 = result[0];
+  q1 = result[1];
+  q2 = result[2];
+}
+
+void lookup3D_h
+       (float table[][][][3],
+        float pMin[3],
+        float pMax[3],
+        half p0, half p1, half p2,
+        output half q0, output half q1, output half q2)
+{
+  lookup3D_f( table, pMin, pMax, p0, p1, p2, q0, q1, q2 );
+}
+
+// Color conversion functions
+
+struct Chromaticities
+{
+    float red[2];
+    float green[2];
+    float blue[2];
+    float white[2];
+};
+
+// float[4][4] RGBtoXYZ(Chromaticities c, float Y)
+// {
+// }
+// 
+// float[4][4] XYZtoRGB(Chromaticities c, float Y)
+// {
+// }
+// 
+// float[3] XYZtoLuv(float XYZ[3], float XYZn[3]);
+// float[3] LuvtoXYZ(float Luv[3], float XYZn[3]);
+//float[3] XYZtoLab(float XYZ[3], float XYZn[3]);
+// float[3] LabtoXYZ(float Lab[3], float XYZn[3]);
+// 
+
+// Vectors/Matrix operations
+
+float[3] mult_f_f3(float f, float x[3])
+{
+  float r[3];
+  for( int k = 0; k < 3; ++k)
+  {
+    r[k] = f * x[k];
+  }
+  return r;
+}
+
+float[3] add_f3_f3(float x[3], float y[3])
+{
+  float r[3];
+  for( int k = 0; k < 3; ++k)
+  {
+    r[k] = x[k] + y[k];
+  }
+  return r;
+}
+
+float[3] sub_f3_f3(float x[3], float y[3])
+{
+  float r[3];
+  for( int k = 0; k < 3; ++k)
+  {
+    r[k] = x[k] - y[k];
+  }
+  return r;
+}
+
+float[3] cross_f3_f3(float x[3], float y[3])
+{
+  float r[3];
+  r[2] = x[0] * y[1] - x[1] * y[0];
+  r[0] = x[1] * y[2] - x[2] * y[1];
+  r[1] = x[2] * y[0] - x[0] * y[2];
+  return r;
+}
+
+float dot_f3_f3(float x[3], float y[3])
+{
+  return x[0] * y[0] + x[1] * y[1] + x[2] * y[2];
+}
+
+float length_f3 (float x[3])
+{
+  return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );
+}
+
+float[3][3] mult_f33_f33 (float A[3][3], float B[3][3])
+{
+  float r[3][3];
+  for( int i = 0; i < 3; ++i)
+  {
+    for( int j = 0; j < 3; ++j)
+    {
+      r[i][j] = 0.0;
+      for( int k = 0; k < 3; ++k)
+      {
+        r[i][j] = r[i][j] + A[i][k] * B[k][j];
+      }
+    }
+  }
+  return r;
+}
+
+float[4][4] mult_f44_f44 (float A[4][4], float B[4][4])
+{
+  float r[4][4];
+  for( int i = 0; i < 4; ++i)
+  {
+    for( int j = 0; j < 4; ++j)
+    {
+      r[i][j] = 0.0;
+      for( int k = 0; k < 4; ++k)
+      {
+        r[i][j] = r[i][j] + A[i][k] * B[k][j];
+      }
+    }
+  }
+  return r;
+}
+
+float[3][3] mult_f_f33 (float f, float A[3][3])
+{
+  float r[3][3];
+  for( int i = 0; i < 3; ++i )
+  {
+    for( int j = 0; j < 3; ++j )
+    {
+      r[i][j] = f * A[i][j];
+    }
+  }
+  return r;
+}
+
+float[4][4] mult_f_f44 (float f, float A[4][4])
+{
+  float r[4][4];
+  for( int i = 0; i < 4; ++i )
+  {
+    for( int j = 0; j < 4; ++j )
+    {
+      r[i][j] = f * A[i][j];
+    }
+  }
+  return r;
+}
+
+float[3][3] add_f33_f33(float A[3][3], float B[3][3])
+{
+  float r[3][3];
+  for( int i = 0; i < 3; ++i )
+  {
+    for( int j = 0; j < 3; ++j )
+    {
+      r[i][j] = A[i][j] + B[i][j];
+    }
+  }
+  return r;
+}
+
+float[4][4] add_f44_f44(float A[4][4], float B[4][4])
+{
+  float r[4][4];
+  for( int i = 0; i < 4; ++i )
+  {
+    for( int j = 0; j < 4; ++j )
+    {
+      r[i][j] = A[i][j] + B[i][j];
+    }
+  }
+  return r;
+}
+
+float[3][3] invert_f33 (float A[3][3])
+{
+  float result[3][3];
+  float det =   A[0][0] * A[1][1] * A[2][2]
+              + A[0][1] * A[1][2] * A[2][0]
+              + A[0][2] * A[1][0] * A[2][1]
+              - A[2][0] * A[1][1] * A[0][2]
+              - A[2][1] * A[1][2] * A[0][0]
+              - A[2][2] * A[1][0] * A[0][1];
+  if( det != 0.0 )
+  {
+    result[0][0] = A[1][1] * A[2][2] - A[1][2] * A[2][1];
+    result[0][1] = A[2][1] * A[0][2] - A[2][2] * A[0][1];
+    result[0][2] = A[0][1] * A[1][2] - A[0][2] * A[1][1];
+    result[1][0] = A[2][0] * A[1][2] - A[1][0] * A[2][2];
+    result[1][1] = A[0][0] * A[2][2] - A[2][0] * A[0][2];
+    result[1][2] = A[1][0] * A[0][2] - A[0][0] * A[1][2];
+    result[2][0] = A[1][0] * A[2][1] - A[2][0] * A[1][1];
+    result[2][1] = A[2][0] * A[0][1] - A[0][0] * A[2][1];
+    result[2][2] = A[0][0] * A[1][1] - A[1][0] * A[0][1];
+
+    return mult_f_f33( 1.0 / det, result);
+  }
+  result = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
+  return result;
+}
+
+
+//---------- Special copyright notice for function invert_f44 -----------//
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2008, Cyrille Berger <cberger@xxxxxxxxxxx>
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+float[4][4] invert_f44 (float A[4][4])
+{
+  
+  
+  if (A[0][3] != 0 || A[1][3] != 0 || A[2][3] != 0 || A[3][3] != 1)
+  {
+    int i;
+    int j;
+    int k;
+    float s[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
+    float t[4][4] = A;
+
+    // Forward elimination
+  
+    for (i = 0; i < 3 ; ++i)
+    {
+      int pivot = i;
+
+      float pivotsize = t[i][i];
+
+      if (pivotsize < 0)
+      {
+        pivotsize = -pivotsize;
+      }
+
+      for (j = i + 1; j < 4; ++j)
+      {
+        float tmp = t[j][i];
+
+        if (tmp < 0)
+          tmp = -tmp;
+
+        if (tmp > pivotsize)
+        {
+          pivot = j;
+          pivotsize = tmp;
+        }
+      }
+      if (pivotsize == 0)
+      {
+        s = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
+        return s;
+      }
+
+      if (pivot != i)
+      {
+        for (j = 0; j < 4; ++j)
+        {
+          float tmp = t[i][j];
+          t[i][j] = t[pivot][j];
+          t[pivot][j] = tmp;
+
+          tmp = s[i][j];
+          s[i][j] = s[pivot][j];
+          s[pivot][j] = tmp;
+        }
+      }
+
+      for (j = i + 1; j < 4; ++j)
+      {
+        float f = t[j][i] / t[i][i];
+        for (k = 0; k < 4; ++k)
+        {
+          t[j][k] = t[j][k] - f * t[i][k];
+          s[j][k] = s[j][k] - f * s[i][k];
+        }
+      }
+    }
+    // Backward substitution
+    for (i = 3; i >= 0; --i)
+    {
+      float f = t[i][i];
+      if ( f == 0)
+      {
+        s = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
+        return s;
+      }
+      for (j = 0; j < 4; ++j)
+      {
+        t[i][j] = t[i][j] / f;
+        s[i][j] = s[i][j] / f;
+      }
+
+      for (j = 0; j < i; ++j)
+      {
+        f = t[j][i];
+  
+        for (k = 0; k < 4; ++k)
+        {
+          t[j][k] = t[j][k] - f * t[i][k];
+          s[j][k] = s[j][k] - f * s[i][k];
+        }
+      }
+    }
+    return s;
+  } else {
+
+    float result[4][4];
+    result[0][0] = A[1][1] * A[2][2] - A[2][1] * A[1][2];
+    result[0][1] = A[2][1] * A[0][2] - A[0][1] * A[2][2];
+    result[0][2] = A[0][1] * A[1][2] - A[1][1] * A[0][2];
+    result[0][3] = 0;
+
+    result[1][0] = A[2][0] * A[1][2] - A[1][0] * A[2][2];
+    result[1][1] = A[0][0] * A[2][2] - A[2][0] * A[0][2];
+    result[1][2] = A[1][0] * A[0][2] - A[0][0] * A[1][2];
+    result[1][3] = 0;
+
+    result[0][0] = A[1][0] * A[2][1] - A[2][0] * A[1][1];
+    result[0][1] = A[2][0] * A[0][1] - A[0][0] * A[2][1];
+    result[0][2] = A[0][0] * A[1][1] - A[1][0] * A[0][1];
+    result[0][3] = 0;
+
+    result[3][0] = 0;
+    result[3][1] = 0;
+    result[3][2] = 0;
+    result[3][3] = 1;
+
+    float r = A[0][0] * result[0][0] + A[0][1] * result[1][0] + A[0][2] * result[2][0];
+
+    if(fabs(r) >= 1)
+    {
+      for(int i = 0; i < 3; ++i)
+      {
+        for(int j = 0; j < 3; ++j)
+        {
+          result[i][j] = result[i][j] / r;
+        }
+      }
+    }
+    else
+    {
+      float mr = fabs(r) / FLT_MIN;
+
+      for (int i = 0; i < 3; ++i)
+      {
+        for (int j = 0; j < 3; ++j)
+        {
+          if (mr > fabs(result[i][j]))
+          {
+            result[i][j] = result[i][j] / r;
+          }
+          else
+          {
+            result = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
+            return result;
+          }
+        }
+      }
+    }
+    result[3][0] = -A[3][0] * result[0][0] - A[3][1] * result[1][0] - A[3][2] * result[2][0];
+    result[3][1] = -A[3][0] * result[0][1] - A[3][1] * result[1][1] - A[3][2] * result[2][1];
+    result[3][2] = -A[3][0] * result[0][2] - A[3][1] * result[1][2] - A[3][2] * result[2][2];
+    return result;
+  }
+  float result[4][4];
+  return result;
+}
+
+// End of special copyright notice
+
+float[3][3] transpose_f33 (float A[3][3])
+{
+  float r[3][3];
+  for( int i = 0; i < 3; ++i)
+  {
+    for( int j = 0; j < 3; ++j)
+    {
+      r[i][j] = A[j][i];
+    }
+  }
+  return r;
+}
+
+float[4][4] transpose_f44 (float A[4][4])
+{
+  float r[4][4];
+  for( int i = 0; i < 4; ++i)
+  {
+    for( int j = 0; j < 4; ++j)
+    {
+      r[i][j] = A[j][i];
+    }
+  }
+  return r;
+}
+
+float[3] mult_f3_f33 (float x[3], float A[3][3])
+{
+  float r[3];
+  for( int i = 0; i < 3; ++i)
+  {
+    r[i] = 0.0;
+    for( int j = 0; j < 3; ++j)
+    {
+      r[i] = r[i] + x[j] * A[j][i];
+    }
+  }
+  return r;
+}
+
+float[3] mult_f3_f44 (float x[3], float A[4][4])
+{
+  float r[3];
+  for( int i = 0; i < 3; ++i)
+  {
+    r[i] = 0.0;
+    for( int j = 0; j < 3; ++j)
+    {
+      r[i] = r[i] + x[j] * A[j][i];
+    }
+    r[i] = r[i] + A[3][i];
+  }
+  float s = 1.0 / (x[0] * A[0][3] + x[1] * A[1][3] + x[2] * A[2][3] + A[3][3]);
+  for( int k = 0; k < 3; ++k)
+  {
+    r[k] = r[k] * s;
+  }
+  return r;
+}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/