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 #include "camera.h" 00020 #include "mesh.h" 00021 00022 #include "subd_dice.h" 00023 #include "subd_patch.h" 00024 #include "subd_split.h" 00025 00026 #include "util_debug.h" 00027 #include "util_math.h" 00028 #include "util_types.h" 00029 00030 CCL_NAMESPACE_BEGIN 00031 00032 /* DiagSplit */ 00033 00034 DiagSplit::DiagSplit() 00035 { 00036 test_steps = 3; 00037 split_threshold = 1; 00038 dicing_rate = 0.1f; 00039 camera = NULL; 00040 } 00041 00042 void DiagSplit::dispatch(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef) 00043 { 00044 subpatches_quad.push_back(sub); 00045 edgefactors_quad.push_back(ef); 00046 } 00047 00048 void DiagSplit::dispatch(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef) 00049 { 00050 subpatches_triangle.push_back(sub); 00051 edgefactors_triangle.push_back(ef); 00052 } 00053 00054 float3 DiagSplit::project(Patch *patch, float2 uv) 00055 { 00056 float3 P; 00057 00058 patch->eval(&P, NULL, NULL, uv.x, uv.y); 00059 if(camera) 00060 P = transform(&camera->worldtoraster, P); 00061 00062 return P; 00063 } 00064 00065 int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend) 00066 { 00067 float3 Plast = make_float3(0.0f, 0.0f, 0.0f); 00068 float Lsum = 0.0f; 00069 float Lmax = 0.0f; 00070 00071 for(int i = 0; i < test_steps; i++) { 00072 float t = i/(float)(test_steps-1); 00073 00074 float3 P = project(patch, Pstart + t*(Pend - Pstart)); 00075 00076 if(i > 0) { 00077 float L = len(P - Plast); 00078 Lsum += L; 00079 Lmax = max(L, Lmax); 00080 } 00081 00082 Plast = P; 00083 } 00084 00085 int tmin = (int)ceil(Lsum/dicing_rate); 00086 int tmax = (int)ceil((test_steps-1)*Lmax/dicing_rate); // XXX paper says N instead of N-1, seems wrong? 00087 00088 if(tmax - tmin > split_threshold) 00089 return DSPLIT_NON_UNIFORM; 00090 00091 return tmax; 00092 } 00093 00094 void DiagSplit::partition_edge(Patch *patch, float2 *P, int *t0, int *t1, float2 Pstart, float2 Pend, int t) 00095 { 00096 if(t == DSPLIT_NON_UNIFORM) { 00097 *P = (Pstart + Pend)*0.5f; 00098 *t0 = T(patch, Pstart, *P); 00099 *t1 = T(patch, *P, Pend); 00100 } 00101 else { 00102 int I = floor(t*0.5f); 00103 *P = interp(Pstart, Pend, (t == 0)? 0: I/(float)t); /* XXX is t faces or verts */ 00104 *t0 = I; 00105 *t1 = t - I; 00106 } 00107 } 00108 00109 void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef, int depth) 00110 { 00111 assert(ef.tu == T(sub.patch, sub.Pv, sub.Pw)); 00112 assert(ef.tv == T(sub.patch, sub.Pw, sub.Pu)); 00113 assert(ef.tw == T(sub.patch, sub.Pu, sub.Pv)); 00114 00115 if(depth == 0) { 00116 dispatch(sub, ef); 00117 return; 00118 } 00119 00120 if(ef.tu == DSPLIT_NON_UNIFORM) { 00121 /* partition edges */ 00122 TriangleDice::EdgeFactors ef0, ef1; 00123 float2 Psplit; 00124 00125 partition_edge(sub.patch, 00126 &Psplit, &ef1.tu, &ef0.tu, sub.Pv, sub.Pw, ef.tu); 00127 00128 /* split */ 00129 int tsplit = T(sub.patch, sub.Pu, Psplit); 00130 ef0.tv = ef.tv; 00131 ef0.tw = tsplit; 00132 00133 ef1.tv = tsplit; 00134 ef1.tw = ef.tw; 00135 00136 /* create subpatches */ 00137 TriangleDice::SubPatch sub0 = {sub.patch, sub.Pu, Psplit, sub.Pw}; 00138 TriangleDice::SubPatch sub1 = {sub.patch, sub.Pu, sub.Pv, Psplit}; 00139 00140 split(sub0, ef0, depth+1); 00141 split(sub1, ef1, depth+1); 00142 } 00143 else if(ef.tv == DSPLIT_NON_UNIFORM) { 00144 /* partition edges */ 00145 TriangleDice::EdgeFactors ef0, ef1; 00146 float2 Psplit; 00147 00148 partition_edge(sub.patch, 00149 &Psplit, &ef1.tu, &ef0.tu, sub.Pw, sub.Pu, ef.tv); 00150 00151 /* split */ 00152 int tsplit = T(sub.patch, sub.Pv, Psplit); 00153 ef0.tv = ef.tw; 00154 ef0.tw = tsplit; 00155 00156 ef1.tv = tsplit; 00157 ef1.tw = ef.tu; 00158 00159 /* create subpatches */ 00160 TriangleDice::SubPatch sub0 = {sub.patch, sub.Pv, Psplit, sub.Pu}; 00161 TriangleDice::SubPatch sub1 = {sub.patch, sub.Pv, sub.Pw, Psplit}; 00162 00163 split(sub0, ef0, depth+1); 00164 split(sub1, ef1, depth+1); 00165 } 00166 else if(ef.tw == DSPLIT_NON_UNIFORM) { 00167 /* partition edges */ 00168 TriangleDice::EdgeFactors ef0, ef1; 00169 float2 Psplit; 00170 00171 partition_edge(sub.patch, 00172 &Psplit, &ef1.tu, &ef0.tu, sub.Pu, sub.Pv, ef.tw); 00173 00174 /* split */ 00175 int tsplit = T(sub.patch, sub.Pw, Psplit); 00176 ef0.tv = ef.tu; 00177 ef0.tw = tsplit; 00178 00179 ef1.tv = tsplit; 00180 ef1.tw = ef.tv; 00181 00182 /* create subpatches */ 00183 TriangleDice::SubPatch sub0 = {sub.patch, sub.Pw, Psplit, sub.Pv}; 00184 TriangleDice::SubPatch sub1 = {sub.patch, sub.Pw, sub.Pu, Psplit}; 00185 00186 split(sub0, ef0, depth+1); 00187 split(sub1, ef1, depth+1); 00188 } 00189 else 00190 dispatch(sub, ef); 00191 } 00192 00193 void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth) 00194 { 00195 if((ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM)) { 00196 /* partition edges */ 00197 QuadDice::EdgeFactors ef0, ef1; 00198 float2 Pu0, Pu1; 00199 00200 partition_edge(sub.patch, 00201 &Pu0, &ef0.tu0, &ef1.tu0, sub.P00, sub.P10, ef.tu0); 00202 partition_edge(sub.patch, 00203 &Pu1, &ef0.tu1, &ef1.tu1, sub.P01, sub.P11, ef.tu1); 00204 00205 /* split */ 00206 int tsplit = T(sub.patch, Pu0, Pu1); 00207 ef0.tv0 = ef.tv0; 00208 ef0.tv1 = tsplit; 00209 00210 ef1.tv0 = tsplit; 00211 ef1.tv1 = ef.tv1; 00212 00213 /* create subpatches */ 00214 QuadDice::SubPatch sub0 = {sub.patch, sub.P00, Pu0, sub.P01, Pu1}; 00215 QuadDice::SubPatch sub1 = {sub.patch, Pu0, sub.P10, Pu1, sub.P11}; 00216 00217 split(sub0, ef0, depth+1); 00218 split(sub1, ef1, depth+1); 00219 } 00220 else if(ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM) { 00221 /* partition edges */ 00222 QuadDice::EdgeFactors ef0, ef1; 00223 float2 Pv0, Pv1; 00224 00225 partition_edge(sub.patch, 00226 &Pv0, &ef0.tv0, &ef1.tv0, sub.P00, sub.P01, ef.tv0); 00227 partition_edge(sub.patch, 00228 &Pv1, &ef0.tv1, &ef1.tv1, sub.P10, sub.P11, ef.tv1); 00229 00230 /* split */ 00231 int tsplit = T(sub.patch, Pv0, Pv1); 00232 ef0.tu0 = ef.tu0; 00233 ef0.tu1 = tsplit; 00234 00235 ef1.tu0 = tsplit; 00236 ef1.tu1 = ef.tu1; 00237 00238 /* create subpatches */ 00239 QuadDice::SubPatch sub0 = {sub.patch, sub.P00, sub.P10, Pv0, Pv1}; 00240 QuadDice::SubPatch sub1 = {sub.patch, Pv0, Pv1, sub.P01, sub.P11}; 00241 00242 split(sub0, ef0, depth+1); 00243 split(sub1, ef1, depth+1); 00244 } 00245 else 00246 dispatch(sub, ef); 00247 } 00248 00249 void DiagSplit::split_triangle(Mesh *mesh, Patch *patch, int shader, bool smooth) 00250 { 00251 TriangleDice::SubPatch sub; 00252 TriangleDice::EdgeFactors ef; 00253 00254 sub.patch = patch; 00255 sub.Pu = make_float2(1.0f, 0.0f); 00256 sub.Pv = make_float2(0.0f, 1.0f); 00257 sub.Pw = make_float2(0.0f, 0.0f); 00258 00259 ef.tu = T(patch, sub.Pv, sub.Pw); 00260 ef.tv = T(patch, sub.Pw, sub.Pu); 00261 ef.tw = T(patch, sub.Pu, sub.Pv); 00262 00263 split(sub, ef); 00264 00265 TriangleDice dice(mesh, shader, smooth, dicing_rate); 00266 dice.camera = camera; 00267 00268 for(size_t i = 0; i < subpatches_triangle.size(); i++) { 00269 TriangleDice::SubPatch& sub = subpatches_triangle[i]; 00270 TriangleDice::EdgeFactors& ef = edgefactors_triangle[i]; 00271 00272 ef.tu = 4; 00273 ef.tv = 4; 00274 ef.tw = 4; 00275 00276 ef.tu = max(ef.tu, 1); 00277 ef.tv = max(ef.tv, 1); 00278 ef.tw = max(ef.tw, 1); 00279 00280 dice.dice(sub, ef); 00281 } 00282 00283 subpatches_triangle.clear(); 00284 edgefactors_triangle.clear(); 00285 } 00286 00287 void DiagSplit::split_quad(Mesh *mesh, Patch *patch, int shader, bool smooth) 00288 { 00289 QuadDice::SubPatch sub; 00290 QuadDice::EdgeFactors ef; 00291 00292 sub.patch = patch; 00293 sub.P00 = make_float2(0.0f, 0.0f); 00294 sub.P10 = make_float2(1.0f, 0.0f); 00295 sub.P01 = make_float2(0.0f, 1.0f); 00296 sub.P11 = make_float2(1.0f, 1.0f); 00297 00298 ef.tu0 = T(patch, sub.P00, sub.P10); 00299 ef.tu1 = T(patch, sub.P01, sub.P11); 00300 ef.tv0 = T(patch, sub.P00, sub.P01); 00301 ef.tv1 = T(patch, sub.P10, sub.P11); 00302 00303 split(sub, ef); 00304 00305 QuadDice dice(mesh, shader, smooth, dicing_rate); 00306 dice.camera = camera; 00307 00308 for(size_t i = 0; i < subpatches_quad.size(); i++) { 00309 QuadDice::SubPatch& sub = subpatches_quad[i]; 00310 QuadDice::EdgeFactors& ef = edgefactors_quad[i]; 00311 00312 ef.tu0 = max(ef.tu0, 1); 00313 ef.tu1 = max(ef.tu1, 1); 00314 ef.tv0 = max(ef.tv0, 1); 00315 ef.tv1 = max(ef.tv1, 1); 00316 00317 dice.dice(sub, ef); 00318 } 00319 00320 subpatches_quad.clear(); 00321 edgefactors_quad.clear(); 00322 } 00323 00324 CCL_NAMESPACE_END 00325