Blender V2.61 - r43446
|
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