Blender V2.61 - r43446

INTERPOLATE.h

Go to the documentation of this file.
00001 
00004 
00005 // This file is part of Wavelet Turbulence.
00006 // 
00007 // Wavelet Turbulence is free software: you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation, either version 3 of the License, or
00010 // (at your option) any later version.
00011 // 
00012 // Wavelet Turbulence is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 // 
00017 // You should have received a copy of the GNU General Public License
00018 // along with Wavelet Turbulence.  If not, see <http://www.gnu.org/licenses/>.
00019 // 
00020 // Copyright 2008 Theodore Kim and Nils Thuerey
00021 // 
00023 #ifndef INTERPOLATE_H
00024 #define INTERPOLATE_H
00025 
00026 #include <iostream>
00027 #include <VEC3.h>
00028 
00029 namespace INTERPOLATE {
00030 
00032 // linear interpolators
00034 static inline float lerp(float t, float a, float b) {
00035     return ( a + t * (b - a) );
00036 }
00037 
00038 static inline float lerp(float* field, float x, float y, int res) {
00039     // clamp backtrace to grid boundaries
00040     if (x < 0.5f) x = 0.5f;
00041     if (x > res - 1.5f) x = res - 1.5f;
00042     if (y < 0.5f) y = 0.5f;
00043     if (y > res - 1.5f) y = res - 1.5f;
00044 
00045     const int x0 = (int)x;
00046     const int y0 = (int)y;
00047     x -= x0;
00048     y -= y0;
00049     float d00, d10, d01, d11;
00050 
00051     // lerp the velocities
00052     d00 = field[x0 + y0 * res];
00053     d10 = field[(x0 + 1) + y0 * res];
00054     d01 = field[x0 + (y0 + 1) * res];
00055     d11 = field[(x0 + 1) + (y0 + 1) * res];
00056     return lerp(y, lerp(x, d00, d10),
00057             lerp(x, d01, d11));
00058 }
00059 
00061 // 3d linear interpolation
00063 static inline float lerp3d(float* field, float x, float y, float z,  int xres, int yres, int zres) {
00064     // clamp pos to grid boundaries
00065     if (x < 0.5) x = 0.5;
00066     if (x > xres - 1.5) x = xres - 1.5;
00067     if (y < 0.5) y = 0.5;
00068     if (y > yres - 1.5) y = yres - 1.5;
00069     if (z < 0.5) z = 0.5;
00070     if (z > zres - 1.5) z = zres - 1.5;
00071 
00072     // locate neighbors to interpolate
00073     const int x0 = (int)x;
00074     const int x1 = x0 + 1;
00075     const int y0 = (int)y;
00076     const int y1 = y0 + 1;
00077     const int z0 = (int)z;
00078     const int z1 = z0 + 1;
00079 
00080     // get interpolation weights
00081     const float s1 = x - (float)x0;
00082     const float s0 = 1.0f - s1;
00083     const float t1 = y - (float)y0;
00084     const float t0 = 1.0f - t1;
00085     const float u1 = z - (float)z0;
00086     const float u0 = 1.0f - u1;
00087 
00088     const int slabSize = xres*yres;
00089     const int i000 = x0 + y0 * xres + z0 * slabSize;
00090     const int i010 = x0 + y1 * xres + z0 * slabSize;
00091     const int i100 = x1 + y0 * xres + z0 * slabSize;
00092     const int i110 = x1 + y1 * xres + z0 * slabSize;
00093     const int i001 = x0 + y0 * xres + z1 * slabSize;
00094     const int i011 = x0 + y1 * xres + z1 * slabSize;
00095     const int i101 = x1 + y0 * xres + z1 * slabSize;
00096     const int i111 = x1 + y1 * xres + z1 * slabSize;
00097 
00098     // interpolate (indices could be computed once)
00099     return ( u0 * (s0 * (t0 * field[i000] +
00100         t1 * field[i010]) +
00101         s1 * (t0 * field[i100] +
00102         t1 * field[i110])) +
00103         u1 * (s0 * (t0 * field[i001] +
00104         t1 * field[i011]) +
00105         s1 * (t0 * field[i101] +
00106         t1 * field[i111])) );
00107 }
00108 
00110 // convert field entries of type T to floats, then interpolate
00112 template <class T> 
00113 static inline float lerp3dToFloat(T* field1,
00114         float x, float y, float z,  int xres, int yres, int zres) {
00115     // clamp pos to grid boundaries
00116     if (x < 0.5) x = 0.5;
00117     if (x > xres - 1.5) x = xres - 1.5;
00118     if (y < 0.5) y = 0.5;
00119     if (y > yres - 1.5) y = yres - 1.5;
00120     if (z < 0.5) z = 0.5;
00121     if (z > zres - 1.5) z = zres - 1.5;
00122 
00123     // locate neighbors to interpolate
00124     const int x0 = (int)x;
00125     const int x1 = x0 + 1;
00126     const int y0 = (int)y;
00127     const int y1 = y0 + 1;
00128     const int z0 = (int)z;
00129     const int z1 = z0 + 1;
00130 
00131     // get interpolation weights
00132     const float s1 = x - (float)x0;
00133     const float s0 = 1.0f - s1;
00134     const float t1 = y - (float)y0;
00135     const float t0 = 1.0f - t1;
00136     const float u1 = z - (float)z0;
00137     const float u0 = 1.0f - u1;
00138 
00139     const int slabSize = xres*yres;
00140     const int i000 = x0 + y0 * xres + z0 * slabSize;
00141     const int i010 = x0 + y1 * xres + z0 * slabSize;
00142     const int i100 = x1 + y0 * xres + z0 * slabSize;
00143     const int i110 = x1 + y1 * xres + z0 * slabSize;
00144     const int i001 = x0 + y0 * xres + z1 * slabSize;
00145     const int i011 = x0 + y1 * xres + z1 * slabSize;
00146     const int i101 = x1 + y0 * xres + z1 * slabSize;
00147     const int i111 = x1 + y1 * xres + z1 * slabSize;
00148 
00149     // interpolate (indices could be computed once)
00150     return (float)(
00151             ( u0 * (s0 * (t0 * (float)field1[i000] +
00152                 t1 * (float)field1[i010]) +
00153                 s1 * (t0 * (float)field1[i100] +
00154                 t1 * (float)field1[i110])) +
00155                 u1 * (s0 * (t0 * (float)field1[i001] +
00156                 t1 * (float)field1[i011]) +
00157                 s1 * (t0 * (float)field1[i101] +
00158                 t1 * (float)field1[i111])) ) );
00159 }
00160 
00162 // interpolate a vector from 3 fields
00164 static inline Vec3 lerp3dVec(float* field1, float* field2, float* field3, 
00165         float x, float y, float z,  int xres, int yres, int zres) {
00166     // clamp pos to grid boundaries
00167     if (x < 0.5) x = 0.5;
00168     if (x > xres - 1.5) x = xres - 1.5;
00169     if (y < 0.5) y = 0.5;
00170     if (y > yres - 1.5) y = yres - 1.5;
00171     if (z < 0.5) z = 0.5;
00172     if (z > zres - 1.5) z = zres - 1.5;
00173 
00174     // locate neighbors to interpolate
00175     const int x0 = (int)x;
00176     const int x1 = x0 + 1;
00177     const int y0 = (int)y;
00178     const int y1 = y0 + 1;
00179     const int z0 = (int)z;
00180     const int z1 = z0 + 1;
00181 
00182     // get interpolation weights
00183     const float s1 = x - (float)x0;
00184     const float s0 = 1.0f - s1;
00185     const float t1 = y - (float)y0;
00186     const float t0 = 1.0f - t1;
00187     const float u1 = z - (float)z0;
00188     const float u0 = 1.0f - u1;
00189 
00190     const int slabSize = xres*yres;
00191     const int i000 = x0 + y0 * xres + z0 * slabSize;
00192     const int i010 = x0 + y1 * xres + z0 * slabSize;
00193     const int i100 = x1 + y0 * xres + z0 * slabSize;
00194     const int i110 = x1 + y1 * xres + z0 * slabSize;
00195     const int i001 = x0 + y0 * xres + z1 * slabSize;
00196     const int i011 = x0 + y1 * xres + z1 * slabSize;
00197     const int i101 = x1 + y0 * xres + z1 * slabSize;
00198     const int i111 = x1 + y1 * xres + z1 * slabSize;
00199 
00200     // interpolate (indices could be computed once)
00201     return Vec3(
00202             ( u0 * (s0 * (t0 * field1[i000] +
00203                 t1 * field1[i010]) +
00204                 s1 * (t0 * field1[i100] +
00205                 t1 * field1[i110])) +
00206                 u1 * (s0 * (t0 * field1[i001] +
00207                 t1 * field1[i011]) +
00208                 s1 * (t0 * field1[i101] +
00209                 t1 * field1[i111])) ) , 
00210             ( u0 * (s0 * (t0 * field2[i000] +
00211                 t1 * field2[i010]) +
00212                 s1 * (t0 * field2[i100] +
00213                 t1 * field2[i110])) +
00214                 u1 * (s0 * (t0 * field2[i001] +
00215                 t1 * field2[i011]) +
00216                 s1 * (t0 * field2[i101] +
00217                 t1 * field2[i111])) ) , 
00218             ( u0 * (s0 * (t0 * field3[i000] +
00219                 t1 * field3[i010]) +
00220                 s1 * (t0 * field3[i100] +
00221                 t1 * field3[i110])) +
00222                 u1 * (s0 * (t0 * field3[i001] +
00223                 t1 * field3[i011]) +
00224                 s1 * (t0 * field3[i101] +
00225                 t1 * field3[i111])) ) 
00226             );
00227 }
00228 
00229 };
00230 #endif