always_inline VecType vec_exp_tanh_float(VecType const & arg) { typedef typename VecType::int_vec int_vec; /* Express e**x = e**g 2**n * = e**g e**( n loge(2) ) * = e**( g + n loge(2) ) */ // black magic VecType x = arg; VecType z = round(VecType(1.44269504088896341f) * x); int_vec n = z.truncate_to_int(); x -= z*VecType(0.693359375f); x -= z*VecType(-2.12194440e-4f); /* Theoretical peak relative error in [-0.5, +0.5] is 3.5e-8. */ VecType p = 1.f + x * (1.00000035762786865234375f + x * (0.4999996721744537353515625f + x * (0.16665561497211456298828125f + x * (4.167006909847259521484375e-2f + x * (8.420792408287525177001953125e-3f + x * 1.386119984090328216552734375e-3f))))); /* multiply by power of 2 */ VecType approx = ldexp_float(p, n); return approx; }
always_inline VecType vec_log_float(VecType x) { typedef typename VecType::int_vec int_vec; int_vec e; x = frexp_float( x, e ); const VecType sqrt_05 = 0.707106781186547524f; const VecType x_smaller_sqrt_05 = mask_lt(x, sqrt_05); e = e + int_vec(x_smaller_sqrt_05); VecType x_add = x; x_add = x_add & x_smaller_sqrt_05; x += x_add - VecType(VecType::gen_one()); VecType y = (((((((( 7.0376836292E-2 * x - 1.1514610310E-1) * x + 1.1676998740E-1) * x - 1.2420140846E-1) * x + 1.4249322787E-1) * x - 1.6668057665E-1) * x + 2.0000714765E-1) * x - 2.4999993993E-1) * x + 3.3333331174E-1) * x * x*x; VecType fe = e.convert_to_float(); y += fe * -2.12194440e-4; y -= 0.5 * x*x; /* y - 0.5 x^2 */ VecType z = x + y; /* ... + x */ return z + 0.693359375 * fe; }
always_inline VecType vec_exp_float(VecType const & arg) { typedef typename VecType::int_vec int_vec; /* Express e**x = e**g 2**n * = e**g e**( n loge(2) ) * = e**( g + n loge(2) ) */ // black magic VecType x = arg; VecType z = round(VecType(1.44269504088896341f) * x); int_vec n = z.truncate_to_int(); x -= z*VecType(0.693359375f); x -= z*VecType(-2.12194440e-4f); /* Theoretical peak relative error in [-0.5, +0.5] is 3.5e-8. */ VecType p = VecType(VecType::gen_one()) + x * (1.00000035762786865234375f + x * (0.4999996721744537353515625f + x * (0.16665561497211456298828125f + x * (4.167006909847259521484375e-2f + x * (8.420792408287525177001953125e-3f + x * 1.386119984090328216552734375e-3f))))); /* multiply by power of 2 */ VecType approx = ldexp_float(p, n); /* handle min/max boundaries */ const VecType maxlogf(88.72283905206835f); // const VecType minlogf(-103.278929903431851103f); const VecType minlogf = -maxlogf; const VecType max_float(std::numeric_limits<float>::max()); const VecType zero = VecType::gen_zero(); VecType too_large = mask_gt(arg, maxlogf); VecType too_small = mask_lt(arg, minlogf); VecType ret = select(approx, max_float, too_large); ret = select(ret, zero, too_small); return ret; }
BallBound<MetricType, VecType>::BallBound(BallBound&& other) : radius(other.radius), center(other.center), metric(other.metric), ownsMetric(other.ownsMetric) { // Fix the other bound. other.radius = 0.0; other.center = VecType(); other.metric = NULL; other.ownsMetric = false; }
always_inline VecType vec_sin_float(VecType const & arg) { typedef typename VecType::int_vec int_vec; const typename VecType::float_type four_over_pi = 1.27323954473516268615107010698011489627567716592367; VecType sign = arg & VecType::gen_sign_mask(); VecType abs_arg = arg & VecType::gen_abs_mask(); VecType y = abs_arg * four_over_pi; int_vec j = y.truncate_to_int(); /* cephes: j=(j+1) & (~1) */ j = (j + int_vec(1)) & int_vec(~1); y = j.convert_to_float(); /* sign based on quadrant */ VecType swap_sign_bit = slli(j & int_vec(4), 29); sign = sign ^ swap_sign_bit; /* polynomial mask */ VecType poly_mask = VecType (mask_eq(j & int_vec(2), int_vec(0))); /* black magic */ static float DP1 = 0.78515625; static float DP2 = 2.4187564849853515625e-4; static float DP3 = 3.77489497744594108e-8; VecType base = ((abs_arg - y * DP1) - y * DP2) - y * DP3; /* [0..pi/4] */ VecType z = base * base; VecType p1 = (( 2.443315711809948E-005 * z - 1.388731625493765E-003) * z + 4.166664568298827E-002) * z * z -0.5f * z + 1.0 ; /* [pi/4..pi/2] */ VecType p2 = ((-1.9515295891E-4 * z + 8.3321608736E-3) * z - 1.6666654611E-1) * z * base + base; VecType approximation = select(p1, p2, poly_mask); return approximation ^ sign; }
always_inline VecType vec_tan_float(VecType const & arg) { typedef typename VecType::int_vec int_vec; const typename VecType::float_type four_over_pi = 1.27323954473516268615107010698011489627567716592367; VecType sign = arg & VecType::gen_sign_mask(); VecType abs_arg = arg & VecType::gen_abs_mask(); VecType y = abs_arg * four_over_pi; int_vec j = y.truncate_to_int(); /* cephes: j=(j+1) & (~1) */ j = (j + int_vec(1)) & int_vec(~1); y = j.convert_to_float(); /* approximation mask */ VecType poly_mask = VecType (mask_eq(j & int_vec(2), int_vec(0))); /* black magic */ static float DP1 = 0.78515625; static float DP2 = 2.4187564849853515625e-4; static float DP3 = 3.77489497744594108e-8; VecType base = ((abs_arg - y * DP1) - y * DP2) - y * DP3; VecType x = base; VecType x2 = x*x; // sollya: fpminimax(tan(x), [|3,5,7,9,11,13|], [|24...|], [-pi/4,pi/4], x); VecType approx = x + x * x2 * (0.3333315551280975341796875 + x2 * (0.1333882510662078857421875 + x2 * (5.3409568965435028076171875e-2 + x2 * (2.443529665470123291015625e-2 + x2 * (3.1127030961215496063232421875e-3 + x2 * 9.3892104923725128173828125e-3))))); //VecType recip = -reciprocal(approx); VecType recip = -1.0 / approx; VecType approximation = select(recip, approx, poly_mask); return approximation ^ sign; }
int RoadComposer::extrude_lines(const Point* point_list, int point_num, int width, float (&tex_coord)[4], V2F2F* vertex_page, int vertex_size, IType* index_page, int index_size, int index_off) { if (point_num < 2) { return EXTRUDE_FAIL; } int line_size = point_num - 1; int v_cursor = 0; for (int idx=0; idx < line_size; idx++) { const Point& p0 = point_list[idx]; const Point& p1 = point_list[idx+1]; VecType a(p0.x, p0.y); VecType b(p1.x, p1.y); VecType e = (b-a); e.normalize(); e *= width; VecType N = VecType(-e.y(), e.x()); VecType S = -N; VecType NE = N + e; VecType NW = N - e; VecType SW = -NE; VecType SE = -NW; if (v_cursor + LINE_MAX_VERT_SIZE > vertex_size) { return EXTRUDE_FAIL; } ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(a + SW).getValue() ); v_cursor++; ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(a + NW).getValue() ); v_cursor++; ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(a + S).getValue() ); v_cursor++; ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(a + N).getValue() ); v_cursor++; ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(b + S).getValue() ); v_cursor++; ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(b + N).getValue() ); v_cursor++; if (idx==line_size-1) { // 最后一段增加尾部 ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(b + S).getValue() ); v_cursor++; ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(b + N).getValue() ); v_cursor++; ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(b + SE).getValue() ); v_cursor++; ASSIGN_2F_ARRAY( vertex_page[v_cursor].xy, VecType(b + NE).getValue() ); v_cursor++; } } _generate_triangle_texCoord(line_size, vertex_size, vertex_page, tex_coord); return _generate_trianges_indices(line_size, index_size, index_page, index_off);; }
VecType backBottomLeft() const { return position + VecType(0, size.y, size.z);}
always_inline VecType vec_log10(VecType arg) { const double rlog10 = 1.0/std::log(10.0); return log(arg) * VecType(rlog10); }
VecType frontBottomRight() const { return position + VecType(size.x, size.y, 0); }
VecType frontBottomLeft() const { return position + VecType(0, size.y, 0);}
VecType frontTopRight() const { return position + VecType(size.x, 0, 0); }
Rect(const VecType& pposition, const VecType& psize = VecType()) noexcept : position(pposition), size(psize) {}
VecType bottomLeft() const { return position + VecType(0, size.y);}
VecType topRight() const { return position + VecType(size.x, 0); }
///Constructs the Rect with a given position and size. Rect(VecType pposition = VecType(), VecType psize = VecType()) noexcept : position(pposition), size(psize) {}
VecType backTopLeft() const { return position + VecType(0, 0, size.z); }
VecType backTopRight() const { return position + VecType(size.x, 0, size.z); }
always_inline VecType vec_log10(VecType arg) { const double rlog10 = 1.0/std::log(10.0); return log(arg) * VecType((typename VecType::float_type)rlog10); }
always_inline VecType vec_log2(VecType arg) { const double rlog2 = 1.0/std::log(2.0); return log(arg) * VecType(rlog2); }