// given a control patch and (u,v) values, find // the surface point and normal Point Bezier::bezpatchinterp(Patch patch, float u, float v, Point &n) { Point p; Point dPdu; Point dPdv; Point trash; std::vector<Point> vcurve(4); std::vector<Point> ucurve(4); bool horizontal = true; bool vertical = false; // build control points for a Bezier curve in v vcurve[0] = bezcurveinterp(patch.getCurve(0, horizontal), u, trash); vcurve[1] = bezcurveinterp(patch.getCurve(1, horizontal), u, trash); vcurve[2] = bezcurveinterp(patch.getCurve(2, horizontal), u, trash); vcurve[3] = bezcurveinterp(patch.getCurve(3, horizontal), u, trash); // build control points for a Bezier curve in u ucurve[0] = bezcurveinterp(patch.getCurve(0, vertical), v, trash); ucurve[1] = bezcurveinterp(patch.getCurve(1, vertical), v, trash); ucurve[2] = bezcurveinterp(patch.getCurve(2, vertical), v, trash); ucurve[3] = bezcurveinterp(patch.getCurve(3, vertical), v, trash); // evaluate surface and derivative for u and v p = bezcurveinterp(vcurve, v, dPdv); p = bezcurveinterp(ucurve, u, dPdu); // take cross product of partials to find normal n = crossP(dPdu, dPdv); n = n / n.length(); Point n2 = crossP(dPdv, dPdu); n2 = n2 / n2.length(); p.saveNormal(n, n2); return p; }
inline void set_exp_vec_simd(F * dest, F f, F curve, unsigned int n) { vec<F> vbase, vcurve(curve * curve * curve * curve); vbase.set_exp(f, curve); unsigned int unroll = n / vec<F>::objects_per_cacheline; do { detail::set_ramp<F, vec<F>::objects_per_cacheline>::exp_mp_iteration(dest, vbase, vcurve); dest += vec<F>::objects_per_cacheline; } while(--unroll); }