void string_slice(const fn_call& fn) { const tu_string& this_str = fn.this_value.to_tu_string(); int len = this_str.utf8_length(); int start = 0; if (fn.nargs >= 1) { start = fn.arg(0).to_int(); if (start < 0) { start = len + start; } } int end = len; if (fn.nargs >= 2) { end = fn.arg(1).to_int(); if (end < 0) { end = len + end; } } start = iclamp(start, 0, len); end = iclamp(end, start, len); fn.result->set_tu_string(this_str.utf8_substring(start, end)); }
void draw_light_rays(float density) // Show post-perspective light rays in ordinary space. { // Find the max necessary boundary of our light ray projections. float proj0, proj1; find_projection_bounds(&proj0, &proj1, s_light_right); vec3 extreme_0 = s_light_right * proj0; vec3 extreme_1 = s_light_right * proj1; vec3 extreme_0_prime = to_persp(extreme_0); vec3 extreme_1_prime = to_persp(extreme_1); // Draw a bunch of rays. Light-buffer ray sampling is linear // in *perspective* space, which means it'll be something else // in world-space. int ray_count = iclamp(int(30 * density), 0, 1000); ray_count = ray_count * 2 + 1; // make it odd for (int i = 0; i < ray_count; i++) { float f = 0.0f; if (ray_count > 1) { f = (float(i) / (ray_count - 1)); } vec3 start = from_persp(extreme_0_prime * (1-f) + extreme_1_prime * f); vec3 v0 = start - s_light_direction * 100000.0f; vec3 v1 = start + s_light_direction * 100000.0f; glColor3f(1, 1, 0); draw_segment(v0, v1); } }
FLOAT interp::spline( FLOAT **d, FLOAT x, FLOAT y, int w, int h ) { FLOAT f[16]; FLOAT xn[4]; if (x<0.0) x=0.0; if (x>=w) x=w-0.01; if (y<0.0) y=0.0; if (y>=h) y=h-0.01; for( int j=0; j<4; j++ ) { for( int i=0; i<4; i++ ) { int hd = (int)x - 1 + i; int v = (int)y - 1 + j; f[4*j+i] = d[iclamp(hd,0,w-1)][iclamp(v,0,h-1)]; } } for( int j=0; j<4; j++ ) xn[j] = spline_cubic( &f[4*j], x - (int)x ); return spline_cubic( xn, y - (int)y ); }
// public substr(start:Number, length:Number) : String void string_substr(const fn_call& fn) { const tu_string& this_str = fn.this_value.to_tu_string(); if (fn.nargs < 1) { return; } // Pull a slice out of this_string. int utf8_len = this_str.utf8_length(); int len = utf8_len; int start = fn.arg(0).to_int(); start = iclamp(start, 0, utf8_len); if (fn.nargs >= 2) { len = fn.arg(1).to_int(); len = iclamp(len, 0, utf8_len); } if (len <= 0) { fn.result->set_tu_string(""); return; } int end = start + len; if (end > utf8_len) { end = utf8_len; } if (start < end) { fn.result->set_tu_string(this_str.utf8_substring(start, end)); } }
void string_substring(const fn_call& fn) { const tu_string& this_str = fn.this_value.to_tu_string(); // Pull a slice out of this_string. int start = 0; int utf8_len = this_str.utf8_length(); int end = utf8_len; if (fn.nargs >= 1) { start = fn.arg(0).to_int(); start = iclamp(start, 0, utf8_len); } if (fn.nargs >= 2) { end = fn.arg(1).to_int(); end = iclamp(end, 0, utf8_len); } if (end < start) tu_swap(&start, &end); // dumb, but that's what the docs say assert(end >= start); fn.result->set_tu_string(this_str.utf8_substring(start, end)); }
static void software_trapezoid( float y0, float y1, float xl0, float xl1, float xr0, float xr1) // Fill the specified trapezoid in the software output buffer. { assert(s_render_buffer); int iy0 = (int) ceilf(y0); int iy1 = (int) ceilf(y1); float dy = y1 - y0; for (int y = iy0; y < iy1; y++) { if (y < 0) { continue; } if (y >= s_rendering_box) { return; } float f = (y - y0) / dy; int xl = (int) ceilf(flerp(xl0, xl1, f)); int xr = (int) ceilf(flerp(xr0, xr1, f)); xl = iclamp(xl, 0, s_rendering_box - 1); xr = iclamp(xr, 0, s_rendering_box - 1); if (xr > xl) { memset(s_render_buffer + y * s_rendering_box + xl, 255, xr - xl); } } }
void root::set_background_alpha(float alpha) { m_background_color.m_a = iclamp(frnd(alpha * 255.0f), 0, 255); }
float bt_array::get_sample(int x, int z) const // Return the altitude from this .bt dataset, at the specified // coordinates. x runs west-to-east, and z runs north-to-south, // unlike UTM. @@ Fix this to make it match UTM??? // // Out-of-bounds coordinates are clamped. { // clamp coordinates. x = iclamp(x, 0, m_width - 1); z = iclamp(z, 0, m_height - 1); int index = 0; char* data = NULL; if (m_cache_height) { // Cache is active. // 'v' coordinate is (m_height - 1 - z) -- the issue // is that BT scans south-to-north, which our z // coordinates run north-to-south. It's easier to // compute cache info using the natural .bt data // order. int v = (m_height - 1 - z); cache_line* cl = &m_cache[x]; if (cl->m_data == NULL || v < cl->m_v0 || v >= cl->m_v0 + m_cache_height) { // Cache line must be refreshed. cl->m_v0 = (v / m_cache_height) * m_cache_height; if (cl->m_data == NULL) { cl->m_data = new Uint8[m_cache_height * m_sizeof_element]; } int fillsize = imin(m_cache_height, m_height - cl->m_v0) * m_sizeof_element; memcpy(cl->m_data, ((Uint8*)m_data) + BT_HEADER_SIZE + (cl->m_v0 + m_height * x) * m_sizeof_element, fillsize); } index = v - cl->m_v0; data = (char*) cl->m_data; } else { // Cache is inactive. Index straight into the raw data. data = (char*) m_data; data += BT_HEADER_SIZE; index = (m_height - 1 - z) + m_height * x; } if (m_float_data) { // raw data is floats. data += index * 4; union { float f; Uint32 u; } raw; raw.u = SDL_SwapLE32(*(Uint32*) data); return raw.f * m_vertical_scale; } else { // Raw data is 16-bit integer. data += index * 2; short y = *(short*)(&SDL_SwapLE16(*(Uint16*) data)); // Niello: bugfix, negative heights are processed normally now // We assume "no data" in heightfield to be 0 elevation. See BT 1.3 format reference notes. if (m_file_ver == BT13 && y == -32768) { y = 0; } return y * m_vertical_scale; } }
float bt_array::get_sample(int x, int z) const // Return the altitude from this .bt dataset, at the specified // coordinates. x runs west-to-east, and z runs north-to-south, // unlike UTM. @@ Fix this to make it match UTM??? // // Out-of-bounds coordinates are clamped. { // clamp coordinates. x = iclamp(x, 0, m_width - 1); z = iclamp(z, 0, m_height - 1); int index = 0; char* data = NULL; if (m_cache_height) { // Cache is active. // 'v' coordinate is (m_height - 1 - z) -- the issue // is that BT scans south-to-north, which our z // coordinates run north-to-south. It's easier to // compute cache info using the natural .bt data // order. int v = (m_height - 1 - z); cache_line* cl = &m_cache[x]; if (cl->m_data == NULL || v < cl->m_v0 || v >= cl->m_v0 + m_cache_height) { // Cache line must be refreshed. cl->m_v0 = (v / m_cache_height) * m_cache_height; if (cl->m_data == NULL) { cl->m_data = new unsigned char[m_cache_height * m_sizeof_element]; } int fillsize = imin(m_cache_height, m_height - cl->m_v0) * m_sizeof_element; // *** MJH modification: only read from memory mapped file if its around if (m_data != NULL) { memcpy(cl->m_data, ((unsigned char*)m_data) + BT_HEADER_SIZE + (cl->m_v0 + m_height * x) * m_sizeof_element, fillsize); } else { // *** MJH modification: else seek and load from the file proper, 64bit addressing Uint64 offset_i64 = (Uint64) BT_HEADER_SIZE + ((Uint64) cl->m_v0 + (Uint64) m_height * (Uint64) x) * (Uint64) m_sizeof_element; lseek64(m_file_handle, offset_i64, SEEK_SET); read(m_file_handle, cl->m_data, fillsize); } } index = v - cl->m_v0; data = (char*) cl->m_data; } else { // Cache is inactive. Index straight into the raw data. data = (char*) m_data; data += BT_HEADER_SIZE; index = (m_height - 1 - z) + m_height * x; } if (m_float_data) { // raw data is floats. data += index * 4; union { float f; Uint32 u; } raw; raw.u = swap_le32(*(Uint32*) data); return raw.f; } else { // Raw data is 16-bit integer. data += index * 2; Uint16 y = swap_le16(*(Uint16*) data); return y; } }