bool mat44::invert() { if (is_orthogonal()) { transpose(); return true; } float det = determinant(); if (!fequal(det, 0.0f)) { det = 1.0f / det; mat44 copy(*this); //to-do det_impl is calculated above in determinant(). //try to gcd m[0][0] = +determinant_impl(copy._11, copy._12, copy._13, copy._21, copy._22, copy._23, copy._31, copy._32, copy._33) * det; m[1][0] = -determinant_impl(copy._10, copy._12, copy._13, copy._20, copy._22, copy._23, copy._30, copy._32, copy._33) * det; m[2][0] = +determinant_impl(copy._10, copy._11, copy._13, copy._20, copy._21, copy._23, copy._30, copy._31, copy._33) * det; m[3][0] = -determinant_impl(copy._10, copy._11, copy._12, copy._20, copy._21, copy._22, copy._30, copy._31, copy._32) * det; m[0][1] = -determinant_impl(copy._01, copy._02, copy._03, copy._21, copy._22, copy._23, copy._31, copy._32, copy._33) * det; m[1][1] = +determinant_impl(copy._00, copy._02, copy._03, copy._20, copy._22, copy._23, copy._30, copy._32, copy._33) * det; m[2][1] = -determinant_impl(copy._00, copy._01, copy._03, copy._20, copy._21, copy._23, copy._30, copy._31, copy._33) * det; m[3][1] = +determinant_impl(copy._00, copy._01, copy._02, copy._20, copy._21, copy._22, copy._30, copy._31, copy._32) * det; m[0][2] = +determinant_impl(copy._01, copy._02, copy._03, copy._11, copy._12, copy._13, copy._31, copy._32, copy._33) * det; m[1][2] = -determinant_impl(copy._00, copy._02, copy._03, copy._10, copy._12, copy._13, copy._30, copy._32, copy._33) * det; m[2][2] = +determinant_impl(copy._00, copy._01, copy._03, copy._10, copy._11, copy._13, copy._30, copy._31, copy._33) * det; m[3][2] = -determinant_impl(copy._00, copy._01, copy._02, copy._10, copy._11, copy._12, copy._30, copy._31, copy._32) * det; m[0][3] = -determinant_impl(copy._01, copy._02, copy._03, copy._11, copy._12, copy._13, copy._21, copy._22, copy._23) * det; m[1][3] = +determinant_impl(copy._00, copy._02, copy._03, copy._10, copy._12, copy._13, copy._20, copy._22, copy._23) * det; m[2][3] = -determinant_impl(copy._00, copy._01, copy._03, copy._10, copy._11, copy._13, copy._20, copy._21, copy._23) * det; m[3][3] = +determinant_impl(copy._00, copy._01, copy._02, copy._10, copy._11, copy._12, copy._20, copy._21, copy._22) * det; return true; } return false; }
bool mat22::invert() { if (is_orthogonal()) { transpose(); return true; } float det = determinant(); if (!fequal(det, 0.0f)) { //calc adjoint matrix swap(this->m[0][0], this->m[1][1]); this->m[0][1] = -this->m[0][1]; this->m[1][0] = -this->m[1][0]; *this *= 1.0f / det; return true; } return false; }
int StatsdClient::send(string key, size_t value, const string &type, float sample_rate) { if (!should_send(sample_rate)) { return 0; } cleanup(key); char buf[256]; if ( fequal( sample_rate, 1.0 ) ) { snprintf(buf, sizeof(buf), "%s%s:%zd|%s", d->ns.c_str(), key.c_str(), value, type.c_str()); } else { snprintf(buf, sizeof(buf), "%s%s:%zd|%s|@%.2f", d->ns.c_str(), key.c_str(), value, type.c_str(), sample_rate); } return send(buf); }
Intersection SquarePlane::GetIntersection(const Ray& r) { Ray r_obj(r.getTransformedCopy(this->transform.invT())); glm::vec3 center(0.f, 0.f, 0.f); glm::vec3 normal(0.f, 0.f, 1.f); float halfside = 1 * 0.5f; if (fequal(r_obj.direction.z, 0.f)) return Intersection(); // since it's a fixed XY plane, this is a simplified ray-plane intersection float t = (center.z - r_obj.origin.z) / r_obj.direction.z; if (t < 0) return Intersection(); glm::vec3 ipoint(r_obj.origin + t * r_obj.direction); if (ipoint.x > center.x + halfside || ipoint.x < center.x - halfside) return Intersection(); if (ipoint.y > center.y + halfside || ipoint.y < center.y - halfside) return Intersection(); glm::vec3 ipoint_world(this->transform.T() * glm::vec4(ipoint, 1.f)); glm::vec4 normal4_world(this->transform.invTransT() * glm::vec4(normal,0.f)); glm::vec3 normal_world(normal4_world); normal_world = glm::normalize(normal_world); float t_world = glm::dot(ipoint_world - r.origin, r.direction); glm::vec3 s_color = Material::GetImageColorInterp(this->GetUVCoordinates(ipoint), this->material->texture); glm::vec4 tangent_o(1,0,0,0); glm::vec3 tangent_world = glm::normalize(glm::vec3(this->transform.invTransT() * tangent_o)); //bitangent computed in Intersection constructor return Intersection(ipoint_world, normal_world, tangent_world, t_world, s_color, this); }
void BirdCameraController::onMouseMove(float x, float y) { if (m_oldMousePos[0] > 0) { float yaw = (x - m_oldMousePos[0]) * 120; float pitch = (y - m_oldMousePos[1]) * 120; m_rot = Matrix4x4::fromRotateX(pitch) * Matrix4x4::fromRotateY(yaw) * m_oldRot; Vector3 xyz[3] = { Vector3(m_rot[0]), Vector3(m_rot[1]), Vector3(m_rot[2]), }; if (!fequal(xyz[0].y, 0)) { xyz[0].y = 0; xyz[0] = xyz[0].normalize(); xyz[2] = xyz[2].normalize(); xyz[1] = xyz[2].crossProduct(xyz[0]); m_rot = Matrix4x4(Matrix3x3(xyz[0].data())); } applyCameraWorldMatrix(); } }
bool set(Type numValue) { DENG2_ASSERT(type == Int || type == UInt || type == Float); switch(type) { case Int: if(value.int32 != dint(numValue)) { value.int32 = dint(numValue); return true; } break; case UInt: if(value.uint32 != duint(numValue)) { value.uint32 = duint(numValue); return true; } break; case Float: if(!fequal(value.float32, dfloat(numValue))) { value.float32 = dfloat(numValue); return true; } break; default: break; } return false; }
static int test_format(void) { plan(282); header(); const size_t buf_size = 1024; char buf[buf_size]; size_t sz; const char *fmt; const char *p, *c, *e; uint32_t len = 0; fmt = "%d %u %i %ld %lu %li %lld %llu %lli" "%hd %hu %hi %hhd %hhu %hhi"; sz = mp_format(buf, buf_size, fmt, 1, 2, 3, (long)4, (long)5, (long)6, (long long)7, (long long)8, (long long)9, (short)10, (short)11, (short)12, (char)13, (char)14, (char)15); p = buf; for (unsigned i = 0; i < 15; i++) { ok(mp_typeof(*p) == MP_UINT, "Test type on step %d", i); ok(mp_decode_uint(&p) == i + 1, "Test value on step %d", i); } sz = mp_format(buf, buf_size, fmt, -1, -2, -3, (long)-4, (long)-5, (long)-6, (long long)-7, (long long)-8, (long long)-9, (short)-10, (unsigned short)-11, (short)-12, (signed char)-13, (unsigned char)-14, (signed char)-15); p = buf; for (int i = 0; i < 15; i++) { uint64_t expects[5] = { UINT_MAX - 1, ULONG_MAX - 4, ULLONG_MAX - 7, USHRT_MAX - 10, UCHAR_MAX - 13 }; if (i % 3 == 1) { ok(mp_typeof(*p) == MP_UINT, "Test type on step %d", i); ok(mp_decode_uint(&p) == expects[i / 3], "Test value on step %d", i); } else { ok(mp_typeof(*p) == MP_INT, "Test type on step %d", i); ok(mp_decode_int(&p) == - i - 1, "Test value on step %d", i); } } char data1[32]; char *data1_end = data1; data1_end = mp_encode_array(data1_end, 2); data1_end = mp_encode_str(data1_end, "ABC", 3); data1_end = mp_encode_uint(data1_end, 11); size_t data1_len = data1_end - data1; assert(data1_len <= sizeof(data1)); char data2[32]; char *data2_end = data2; data2_end = mp_encode_int(data2_end, -1234567890); data2_end = mp_encode_str(data2_end, "DEFGHIJKLMN", 11); data2_end = mp_encode_uint(data2_end, 321); size_t data2_len = data2_end - data2; assert(data2_len <= sizeof(data2)); fmt = "%d NIL [%d %b %b] this is test" "[%d %%%% [[ %d {%s %f %% %.*s %lf %.*s NIL}" "%p %d %.*p ]] %d%d%d]"; #define TEST_PARAMS 0, 1, true, false, -1, 2, \ "flt", 0.1, 6, "double#ignored", 0.2, 0, "ignore", \ data1, 3, data2_len, data2, 4, 5, 6 sz = mp_format(buf, buf_size, fmt, TEST_PARAMS); p = buf; e = buf + sz; c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 0, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_NIL, "type"); mp_decode_nil(&p); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_ARRAY, "type"); ok(mp_decode_array(&p) == 3, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 1, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_BOOL, "type"); ok(mp_decode_bool(&p) == true, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_BOOL, "type"); ok(mp_decode_bool(&p) == false, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_ARRAY, "type"); ok(mp_decode_array(&p) == 5, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_INT, "type"); ok(mp_decode_int(&p) == -1, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_ARRAY, "type"); ok(mp_decode_array(&p) == 1, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_ARRAY, "type"); ok(mp_decode_array(&p) == 5, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 2, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_MAP, "type"); ok(mp_decode_map(&p) == 3, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_STR, "type"); c = mp_decode_str(&p, &len); ok(len == 3, "decode"); ok(memcmp(c, "flt", 3) == 0, "compare"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_FLOAT, "type"); ok(fequal(mp_decode_float(&p), 0.1), "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_STR, "type"); c = mp_decode_str(&p, &len); ok(len == 6, "decode"); ok(memcmp(c, "double", 6) == 0, "compare"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_DOUBLE, "type"); ok(dequal(mp_decode_double(&p), 0.2), "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_STR, "type"); c = mp_decode_str(&p, &len); ok(len == 0, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_NIL, "type"); mp_decode_nil(&p); c = p; ok(mp_check(&c, e) == 0, "check"); ok(((size_t)(c - p) == data1_len) && memcmp(p, data1, data1_len) == 0, "compare"); p = c; c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 3, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_INT, "type"); ok(mp_decode_int(&p) == -1234567890, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_STR, "type"); c = mp_decode_str(&p, &len); ok(len == 11, "decode"); ok(memcmp(c, "DEFGHIJKLMN", 11) == 0, "compare"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 321, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 4, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 5, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 6, "decode"); ok(p == e, "nothing more"); ok(sz < 70, "no magic detected"); for (size_t lim = 0; lim <= 70; lim++) { memset(buf, 0, buf_size); size_t test_sz = mp_format(buf, lim, fmt, TEST_PARAMS); ok(test_sz == sz, "return value on step %d", (int)lim); bool all_zero = true; for(size_t z = lim; z < buf_size; z++) all_zero = all_zero && (buf[z] == 0); ok(all_zero, "buffer overflow on step %d", (int)lim); } #undef TEST_PARAMS footer(); return check_plan(); }
/***************************************************************************** Function name: RootBrent() Purpose : Calculate the surface temperature in the absence of snow Required : int y - Row number of current pixel int x - Column number of current pixel float LowerBound - Lower bound for root float UpperBound - Upper bound for root float (*Function)(float Estimate, va_list ap) ... - Variable arguments The number and order of arguments has to be appropriate for the Function pointed to, since the list of arguments after Nargs will be passed on to Function. See the appropriate Function for the correct arguments. Returns : float b - Effective surface temperature (C) Modifies : none Comments : *****************************************************************************/ float RootBrent(int y, int x, float LowerBound, float UpperBound, float (*Function) (float Estimate, va_list ap), ...) { const char *Routine = "RootBrent"; char ErrorString[MAXSTRING + 1]; va_list ap; /* Used in traversing variable argument list */ float a; float b; float c=0; float d=0; float e=0; float fa; float fb; float fc; float m; float p; float q; float r; float s; float tol; int i; int j; int eval = 0; sprintf(ErrorString, "%s: y = %d, x = %d", Routine, y, x); /* initialize variable argument list */ a = LowerBound; b = UpperBound;; va_start(ap, Function); fa = Function(a, ap); eval++; va_start(ap, Function); fb = Function(b, ap); eval++; /* if root not bracketed attempt to bracket the root */ j = 0; while ((fa * fb) >= 0 && j < MAXTRIES) { a -= TSTEP; b += TSTEP; va_start(ap, Function); fa = Function(a, ap); eval++; va_start(ap, Function); fb = Function(b, ap); eval++; j++; } if ((fa * fb) >= 0) { // printf("Error in RootBrent%s: y = %d, x = %d, tries = %d,\na:b = %f:%f fa:fb = %f:%f\n", Routine, y, x, j, a,b,fa,fb); // ReportError(ErrorString, 34); return(-99); } fc = fb; for (i = 0; i < MAXITER; i++) { if (fb * fc > 0) { c = a; fc = fa; d = b - a; e = d; } if (fabs(fc) < fabs(fb)) { a = b; b = c; c = a; fa = fb; fb = fc; fc = fa; } tol = 2 * MACHEPS * fabs(b) + T; m = 0.5 * (c - b); if (fabs(m) <= tol || fequal(fb, 0.0)) { va_end(ap); return b; } else { if (fabs(e) < tol || fabs(fa) <= fabs(fb)) { d = m; e = d; } else { s = fb / fa; if (fequal(a, c)) { /* linear interpolation */ p = 2 * m * s; q = 1 - s; } else { /* inverse quadratic interpolation */ q = fa / fc; r = fb / fc; p = s * (2 * m * q * (q - r) - (b - a) * (r - 1)); q = (q - 1) * (r - 1) * (s - 1); } if (p > 0) q = -q; else p = -p; s = e; e = d; if ((2 * p) < (3 * m * q - fabs(tol * q)) && p < fabs(0.5 * s * q)) d = p / q; else { d = m; e = d; } } a = b; fa = fb; b += (fabs(d) > tol) ? d : ((m > 0) ? tol : -tol); va_start(ap, Function); fb = Function(b, ap); eval++; } } // printf("Error in RootBrent%s: y = %d, x = %d, tries = %d,\na:b = %f:%f fa:fb = %f:%f", Routine, y, x, j, a,b,fa,fb); // ReportError(ErrorString, 33); return(-99); }
glm::vec3 DirectLightingIntegrator::DirectLights(Ray r, glm::vec3& direction, float& bxdf_pdf, Intersection isx, glm::vec3& energy){ glm::vec3 colour(0.0f); Intersection intersection; intersection = isx;//intersection_engine->GetIntersection(r); glm::vec3 offset_point = intersection.point + 0.1f * intersection.normal; if(intersection.object_hit == NULL){ return colour; } if(intersection.object_hit->material->is_light_source){ return intersection.object_hit->material->EvaluateScatteredEnergy(intersection, glm::vec3(0.0f), -r.direction); } // isx_point = intersection.point; glm::vec3 light_colour; float light_pdf; float w_f, w_g; int light_nSamples = 1; int brdf_nSamples = 1; float brdf_pdf; Ray omega_j; glm::vec3 light_final_colour(0.0f); Geometry* light = scene->lights.at(rand() % scene->lights.size()); for(int i = 0; i < light_nSamples; i++){ float x = unif_distribution(mersenne_generator); float y = unif_distribution(mersenne_generator); Intersection rand_intersection = light->SampleLight(x ,y, offset_point, intersection_engine); if(rand_intersection.object_hit != light){ continue; } omega_j = Ray(offset_point, glm::normalize(rand_intersection.point - offset_point)); glm::vec3 wi; intersection.object_hit->material->SampleAndEvaluateScatteredEnergy(intersection, -r.direction, wi, brdf_pdf); light_pdf = rand_intersection.object_hit->RayPDF(rand_intersection, omega_j); if(fequal(light_pdf, 0.0f)){ continue; } light_colour = light->material->EvaluateScatteredEnergy( rand_intersection, -r.direction, -omega_j.direction ); glm::vec3 brdf_colour = intersection.object_hit->material->EvaluateScatteredEnergy( intersection, -r.direction, omega_j.direction ); w_g = glm::pow(light_nSamples * light_pdf, 2.0f) / (glm::pow(brdf_nSamples * brdf_pdf, 2.0f) + glm::pow(light_nSamples * light_pdf, 2.0f)); light_final_colour += w_g * light_colour * brdf_colour * glm::abs(glm::dot((omega_j.direction), (intersection.normal))) / light_pdf; } light_final_colour = light_final_colour * float(scene->lights.size()) / float(light_nSamples); //BIS glm::vec3 brdf_final_colour(0.0f); glm::vec3 brdf_colourb = intersection.object_hit->material->SampleAndEvaluateScatteredEnergy (intersection, -r.direction, omega_j.direction, brdf_pdf); direction = omega_j.direction; bxdf_pdf = brdf_pdf; energy = brdf_colourb; omega_j.origin = intersection.point + 0.0001f * omega_j.direction; Ray lightRay = Ray(omega_j.origin, omega_j.direction); Intersection light_inter = intersection_engine->GetIntersection(lightRay); light_nSamples = 1; if(!fequal(brdf_pdf, 0.0f)){ light_pdf = intersection.object_hit->RayPDF(light_inter, omega_j); if(light_inter.object_hit && light_inter.object_hit == light){ if(!fequal(light_pdf, 0.0f)){ w_f = glm::pow(brdf_nSamples * brdf_pdf, 2.0f) / (glm::pow(brdf_nSamples * brdf_pdf, 2.0f) + glm::pow(light_nSamples * light_pdf, 2.0f)); } else{ w_f = 1.0f; } light_colour = light_inter.object_hit->material->EvaluateScatteredEnergy( light_inter, -r.direction, -omega_j.direction ); } else{ w_f = 0.0f; } float abs_cos = glm::abs(glm::dot((omega_j.direction), (intersection.normal))); brdf_final_colour = w_f * light_colour * brdf_colourb * abs_cos / (brdf_pdf); } return colour = light_final_colour + brdf_final_colour; }
void MeshBuilder::splitVertexDiscontinuities( DiscontinuousVertexMap* vmad ) { int dim = vmad->dimensions(); if ( dim > 32 ) dim = 32; float data0[32]; float data1[32]; for ( int i = 0 ; i < vertices() ; ++i ) { Vertex* vert = getVertex(i); if ( vert->polygons() > 1 ) { Polygon* poly0 = vert->getPolygon(0); bool poly0ok = vmad->getValue( vert->index(), poly0->index(), data0, dim ); if ( poly0ok ) { for ( int j = 1; j < vert->polygons() ; ++j ) { Polygon* poly1 = vert->getPolygon(j); if ( poly1 != poly0 ) { bool poly1ok = vmad->getValue( vert->index(), poly1->index(), data1, dim ); if ( poly1ok ) { if ( !fequal(data0,data1,dim) ) { // discontinuity, split vertex mb::Vertex* vert2 = vert->clone(); poly1->setVertex( poly1->getIndex(vert), vert2 ); --j; // adjust index as vert has one poly less } } } // if ( poly1 != poly0 ) } } // if ( poly0ok ) } } #ifdef _DEBUG // ensure succesful split for ( int i = 0 ; i < vertices() ; ++i ) { Vertex* vert = getVertex(i); if ( vert->polygons() > 1 ) { Polygon* poly0 = vert->getPolygon(0); bool poly0ok = vmad->getValue( vert->index(), poly0->index(), data0, dim ); if ( poly0ok ) { // check other vertex polys for ( int j = 1 ; j < vert->polygons() ; ++j ) { Polygon* poly1 = vert->getPolygon(j); bool poly1ok = vmad->getValue( vert->index(), poly1->index(), data1, dim ); if ( poly1ok ) { assert( fequal(data0,data1,dim) ); } } } } // if ( vert->polygons() > 1 ) } #endif }
void propagate_locals(object_planar* instance) { #ifdef PATH_EXT_SET if (enigma_user::path_update()) {instance->speed = 0; return;} #endif if (fnzero(instance->gravity) || fnzero(instance->friction)) { double hb4 = instance->hspeed.rval.d, vb4 = instance->vspeed.rval.d; int sign = (instance->speed > 0) - (instance->speed < 0); if (instance->hspeed!=0) instance->hspeed.rval.d -= (sign * instance->friction) * cos(instance->direction.rval.d * M_PI/180); if ((hb4>0 && instance->hspeed.rval.d<0) || (hb4<0 && instance->hspeed.rval.d>0)) instance->hspeed.rval.d=0; if (instance->vspeed!=0) instance->vspeed.rval.d -= (sign * instance->friction) * -sin(instance->direction.rval.d * M_PI/180); if ((vb4>0 && instance->vspeed.rval.d<0) || (vb4<0 && instance->vspeed.rval.d>0)) instance->vspeed.rval.d=0; if (fequal(instance->gravity_direction, 270)) { instance->vspeed.rval.d += (instance->gravity); } else if (fequal(instance->gravity_direction, 180)) { instance->hspeed.rval.d -= (instance->gravity); } else if (fequal(instance->gravity_direction, 90)) { instance->vspeed.rval.d -= (instance->gravity); } else if (fequal(instance->gravity_direction, 0)) { instance->hspeed.rval.d += (instance->gravity); } else { instance->hspeed.rval.d += (instance->gravity) * cos(instance->gravity_direction * M_PI/180); instance->vspeed.rval.d += (instance->gravity) *-sin(instance->gravity_direction * M_PI/180); } /* if(instance->speed.rval.d<0) //instance->direction.rval.d = fmod(instance->direction.rval.d + 180, 360), instance->speed. rval.d = -hypotf(instance->hspeed.rval.d, instance->vspeed.rval.d); else instance->direction.rval.d = fmod(instance->direction.rval.d, 360), instance->speed. rval.d = hypotf(instance->hspeed.rval.d, instance->vspeed.rval.d); if(instance->direction.rval.d < 0) instance->direction.rval.d += 360;*/ instance->speed.rval.d = instance->speed.rval.d < 0? -hypot(instance->hspeed.rval.d, instance->vspeed.rval.d) : hypot(instance->hspeed.rval.d, instance->vspeed.rval.d); if (fabs(instance->speed.rval.d) > 1e-12) instance->direction.rval.d = fmod((atan2(-instance->vspeed.rval.d, instance->hspeed.rval.d) * (180/M_PI)) + (instance->speed.rval.d < 0? 180 : 360), 360); } instance->x += instance->hspeed.rval.d; instance->y += instance->vspeed.rval.d; }
// Treating Ray r as the ray from the camera glm::vec3 Integrator::DirectLightingIntegratorTraceRayWithClouds(Ray &r, unsigned int depth, float ¤t_brdf_PDF, glm::vec3 ¤t_BxDFCol_Dot) { // Declaring Party float light_PDF, BxDF_PDF; float light_importance, bxdf_importance; glm::vec3 light_incoming, LTE_LIGHT, LTE_BxDF; // Get intersection from Ray r Intersection isx = intersection_engine->GetIntersection(Ray(r.origin + 0.0001f * r.direction, r.direction)); // Random Light Geometry* rand_light = scene->lights.at(qrand() % scene->lights.size()); // Random point on light Intersection sample_isx = rand_light->GetSamplePoint(isx.normal); // Cloud Lighting glm::vec3 cloud_colorLS = glm::vec3(0.f); QList<Geometry*> skip; float cloud_opacityLS = 0.f; if (isx.object_hit != NULL && isx.object_hit->material->is_cloud) { cloud_colorLS = CloudVisibility(isx, sample_isx, r, cloud_opacityLS, skip); } // If object no object is hit then return black // If object hit is a light, return its texturecolor * basecolor if (isx.object_hit == NULL) { current_brdf_PDF = -1; // this ends the trace return glm::vec3(0.0f); } else if (isx.object_hit->material->is_light_source) { if (depth > 0) { current_brdf_PDF = -1; // this ends the trace return glm::vec3(0.f); } else { current_brdf_PDF = -1; // this ends the trace return isx.texture_color * isx.object_hit->material->base_color; } } // RAY CONVENTION // All rays are pointing away from the geometry // wj = Ray from geometry to the light glm::vec3 wj_dir = glm::normalize(sample_isx.point - isx.point); Ray wj = Ray(isx.point + wj_dir * 0.0001f, wj_dir); // wo is the ray from the object to the camera in the first iteration // wo is otherwise the old wj reversed glm::vec3 wo = -r.direction; // Get a random BxDF which will be passed into all ESE formulas as a pointer to keep the BxDF consistant // In a regular material, this is just the first BxDF on the QList as there are no other BxDFs // However, in a weighted material, this will help with consistancy BxDF* BxDF_RAND = isx.object_hit->material->GetRandomBxDF(); /** * Light Sampling **/ // Shadow Testing // Check if wj is obstructed, if it return 0 Intersection obs_isx = intersection_engine->GetIntersectionSkipThis(Ray(wj.origin + 0.001f * wj.direction, wj.direction), skip); if (obs_isx.object_hit != rand_light) { light_incoming = glm::vec3(0.0f); // radiance light_PDF = 0.f; } else { // hit rand_light // Calculate the LightESE light_incoming = rand_light->material->EvaluateScatteredEnergy(sample_isx, wo, -wj.direction, BxDF_RAND); // light_PDF tells us if the light hit it light_PDF = obs_isx.object_hit->RayPDF(obs_isx, wj); // if no light hit it return 0 if (light_PDF <= 0.0001f) { light_PDF = 0.f; light_incoming = glm::vec3(0.0f); } } // Convert to Normal Space to pass into the PDF function for BxDF // Refactor? glm::mat3 T = glm::mat3(isx.tangent, isx.bitangent, isx.normal); T = glm::transpose(T); glm::vec3 pdf_wi = T * wj.direction; glm::vec3 pdf_wo = T * wo; // Calculate the BxDF_PDF BxDF_PDF = BxDF_RAND->PDF(pdf_wo, pdf_wi); float dot_wj_nor = glm::abs(glm::dot(wj.direction, isx.normal)); // Calculate weighting for the materials. glm::vec3 BRDF_color = isx.object_hit->material->EvaluateScatteredEnergy(isx, wo, wj.direction, BxDF_RAND); // First Half of the Equation if (fequal(light_PDF, 0.f)) { LTE_LIGHT = glm::vec3(0.0f); // Set MIS to 0 mostly because if BxDF_PDF is also 0 then it would be NaN // If light_PDF is 0, then MIS should be zero anyway light_importance = 0.f; } else { LTE_LIGHT = BRDF_color * light_incoming * dot_wj_nor / light_PDF; light_importance = light_PDF * light_PDF / (light_PDF * light_PDF + BxDF_PDF * BxDF_PDF); } /** * BxDF Sampling **/ // Generate the new ray wj // Calculate BRDF_color from that ray BRDF_color = isx.object_hit->material->SampleAndEvaluateScatteredEnergy(isx, wo, wj.direction, BxDF_PDF, BxDF_RAND); // // Cloud Lighting glm::vec3 cloud_colorBS = glm::vec3(0.f); skip.empty(); float cloud_opacityBS = 0.f; if (isx.object_hit != NULL && isx.object_hit->material->is_cloud) { cloud_colorBS = CloudVisibility(isx, sample_isx, r, cloud_opacityBS, skip); } // Shadow Test obs_isx = intersection_engine->GetIntersectionSkipThis(Ray(wj.origin + 0.001f * wj.direction, wj.direction), skip); if (obs_isx.object_hit != rand_light) { light_incoming = glm::vec3(0.0f); // radiance light_PDF = 0.f; } else { light_incoming = rand_light->material->EvaluateScatteredEnergy(obs_isx, wo, -wj.direction, BxDF_RAND); // light_PDF tells us if the light hit it light_PDF = obs_isx.object_hit->RayPDF(obs_isx, wj); if (light_PDF < 0.0001f) { light_PDF = 0.f; } } dot_wj_nor = glm::abs(glm::dot(wj.direction, isx.normal)); if (fequal(BxDF_PDF, 0.0f)) { LTE_BxDF = glm::vec3(0.0f); // Set MIS to 0 mostly because if BxDF_PDF is also 0 then it would be NaN // If BxDF_PDF is 0, then MIS should be zero anyway bxdf_importance = 0.f; } else { LTE_BxDF = BRDF_color * light_incoming * dot_wj_nor / BxDF_PDF; bxdf_importance = BxDF_PDF * BxDF_PDF / (light_PDF * light_PDF + BxDF_PDF * BxDF_PDF); } /** -------------------------------------- * QUIK Change this to see other LTE outcomes * LTE_LIGHT = first half of the equation with the light * LTE_BxDF = second half of the equation with the BxDF * light_importance = MIS for LTE_LIGHT * bxdf_importance = MIS for LTE_BxDF * --------------------------------------- */ // Set up actual return // glm::vec3 LTE = light_importance * LTE_LIGHT + bxdf_importance * LTE_BxDF; glm::vec3 LTE = cloud_colorLS + (1.f-cloud_opacityLS) * (light_importance * LTE_LIGHT) + cloud_colorBS + (1.f-cloud_opacityBS) * (bxdf_importance * LTE_BxDF); // Return for indirect lighting r = wj; // isx point is already updated from above current_brdf_PDF = BxDF_PDF; current_BxDFCol_Dot = BRDF_color * dot_wj_nor; // Actual Return return LTE; }
void CheckOut(int CanopyRadAttOption, LAYER Veg, LAYER Soil, VEGTABLE *VType, SOILTABLE *SType, MAPSIZE *Map, TOPOPIX **TopoMap, VEGPIX **VegMap, SOILPIX **SoilMap) { int y, x, i, j; int *count = NULL, *scount = NULL; float a, b, l, Taud, Taub20, Taub40, Taub60, Taub80; int npixels; if (!(count = static_cast<int*>(calloc(Veg.NTypes, sizeof(int))))) { ReportError("Checkout", 1); } if (!(scount = static_cast<int *>(calloc(Soil.NTypes, sizeof(int))))) { ReportError("Checkout", 1); } for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { if (VegMap[y][x].Veg < 1 || VegMap[y][x].Veg > Veg.NTypes) { printf("veg value %d out of range \n", VegMap[y][x].Veg); exit(-1); } count[VegMap[y][x].Veg - 1]++; if (SoilMap[y][x].Soil < 1 || SoilMap[y][x].Soil > Soil.NTypes) { printf("soil value %d out of range \n", SoilMap[y][x].Soil); exit(-1); } scount[SoilMap[y][x].Soil - 1]++; } } } i = 0; for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { i = i + 1; } } } printf("\nBasin has %d active pixels \n", i); npixels = i; printf("\nThe following VEG types are in the current basin \n"); for (i = 0; i < Veg.NTypes; i++) { if (count[i] > 0) printf ("Class # %d of Type: %s has fraction basin area: %5.3f\n", i + 1, VType[i].Desc, (float) count[i] / (float) npixels); VType[i].TotalDepth = 0.0; for (y = 0; y < VType[i].NSoilLayers; y++) { VType[i].TotalDepth += VType[i].RootDepth[y]; } } printf("\nThe following SOIL types are in the current basin \n"); for (i = 0; i < Soil.NTypes; i++) if (scount[i] > 0) printf ("Class # %d of Type: %s has fraction basin area: %5.3f\n", i + 1, SType[i].Desc, (float) scount[i] / (float) npixels); printf("\nSome estimates for current vegetation specification\n"); for (i = 0; i < Veg.NTypes; i++) { if (count[i] > 0) { printf("\nVegetation Type: %s\n", VType[i].Desc); printf("2meter wind speed fraction of ref level %1.3f\n", VType[i].USnow); if (VType[i].OverStory) { for (j = 0; j < 12; j++) { if (fequal(VType[i].LAIMonthly[0][j], 0.0)) { printf("Overstory LAI must be > 0\n"); exit(-1); } } /* printf("Overstory LAI July %2.3f Effective LAI July %2.3f\n", VType[i].LAIMonthly[0][6]);*/ if (CanopyRadAttOption == VARIABLE) { a = VType[i].LeafAngleA; b = VType[i].LeafAngleB; l = VType[i].LAIMonthly[0][6] / VType[i].ClumpingFactor; if (l == 0) Taud = 1.0; else Taud = exp(-b * l) * ((1 - a * l) * exp(-a * l) + (a * l) * (a * l) * evalexpint(1, a * l)); Taub20 = exp(-l * (VType[i].LeafAngleA / 0.342 + VType[i].LeafAngleB)); Taub40 = exp(-l * (VType[i].LeafAngleA / 0.642 + VType[i].LeafAngleB)); Taub60 = exp(-l * (VType[i].LeafAngleA / 0.866 + VType[i].LeafAngleB)); Taub80 = exp(-l * (VType[i].LeafAngleA / 0.984 + VType[i].LeafAngleB)); printf("Solar Altitude 20 deg Tbeam %f Tdiff %f\n", Taub20, Taud); printf("Solar Altitude 40 deg Tbeam %f Tdiff %f\n", Taub40, Taud); printf("Solar Altitude 60 deg Tbeam %f Tdiff %f\n", Taub60, Taud); printf("Solar Altitude 80 deg Tbeam %f Tdiff %f\n", Taub80, Taud); } } } } for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { if (SoilMap[y][x].Depth <= VType[VegMap[y][x].Veg - 1].TotalDepth) { printf("Error for class %d of Type %s \n", VegMap[y][x].Veg, VType[VegMap[y][x].Veg - 1].Desc); printf("%d %d Soil depth is %f, Root depth is %f \n", y,x,SoilMap[y][x].Depth, VType[VegMap[y][x].Veg - 1].TotalDepth); exit(-1); } } } } if (count) { free(count); } if (scount) { free(scount); } }
void sample_triangle(const vec2f ¢er, const vec2f verts[3], xsurface_test &surf) { const vec2f *p0, *p1, *p2; if (verts[0].y > verts[1].y) { p0 = verts + 1; p1 = verts; } else { p0 = verts; p1 = verts + 1; } if (p0->y > verts[2].y) { p2 = p0; p0 = verts + 2; } else p2 = verts + 2; if (p1->y > p2->y) std::swap(p1, p2); assert(p0->y <= p1->y && p1->y <= p2->y); float x0, x1, t0, t1, dx0, dx1, dt0, dt1; float dy10 = p1->y - p0->y; float dy20 = p2->y - p0->y; float dy21 = p2->y - p1->y; float y = std::floor(p0->y + 1 - center.y) + center.y; float dy = y - p0->y; bool p1_first; if (!fequal(dy10, 0)) { assert(!fequal(dy20, 0)); dt0 = 1.0f / dy20; float dx20 = p2->x - p0->x; p1_first = p1->x <= (p0->x + dx20 * dt0 * dy10); if (p1_first) { dt1 = dt0; dt0 = 1.0f / dy10; dx0 = (p1->x - p0->x) * dt0; dx1 = dx20 * dt1; } else { dt1 = 1.0f / dy10; dx0 = dx20 * dt0; dx1 = (p1->x - p0->x) * dt1; } x0 = p0->x + dy * dx0; x1 = p0->x + dy * dx1; t0 = dy * dt0; t1 = dy * dt1; for (; y < p1->y; y += 1) { sample_scan_line(y, center.x, x0, x1, surf); x0 += dx0; x1 += dx1; t0 += dt0; t1 += dt1; } } else { p1_first = p1->x < p0->x; } if (!fequal(dy21, 0)) { assert(!fequal(dy20, 0)); dy = y - p1->y; if (p1_first) { dt0 = 1.0f / dy21; dx0 = (p2->x - p1->x) * dt0; x0 = p1->x + dy * dx0; t0 = dy * dt0; } else { dt1 = 1.0f / dy21; dx1 = (p2->x - p1->x) * dt1; x1 = p1->x + dy * dx1; t1 = dy * dt1; } // NOTICE: include the upper scan line for (; y <= p2->y; y += 1) { sample_scan_line(y, center.x, x0, x1, surf); x0 += dx0; x1 += dx1; t0 += dt0; t1 += dt1; } } }
float evalexpint(int n, float x) { int i, ii, nm1; float a, b, c, d, del, fact, h, psi, ans; nm1 = n - 1; if (n < 0 || x < 0.0 || (fequal(x, 0.0) && (n == 0 || n == 1))) { printf("bad args to EvalExpInt \n"); exit(-1); } else { if (n == 0) ans = exp(-x) / x; else { if (x == 0 && nm1 > 0) ans = 1.0 / nm1; else { if (x > 1.0) { b = x + n; c = 1.0 / FPMIN; d = 1.0 / b; h = d; for (i = 1; i <= MAXIT; i++) { a = -i * (nm1 + i); b += 2.0; d = 1.0 / (a * d + b); c = b + a / c; del = c * d; h *= del; if (fabs(del - 1.0) < EVALEXPONENT_EPS) { ans = h * exp(-x); return ans; } } printf("error in expint\n"); exit(-1); } else { ans = (nm1 != 0 ? 1.0 / nm1 : -log(x) - EULER); fact = 1.0; for (i = 1; i <= MAXIT; i++) { fact *= -x / i; if (i != nm1) del = -fact / (i - nm1); else { psi = -EULER; for (ii = 1; ii <= nm1; ii++) psi += 1.0 / ii; del = fact * (-log(x) + psi); } ans += del; if (fabs(del) < fabs(ans) * EVALEXPONENT_EPS) return ans; } printf("error in routine \n"); exit(-1); } } } } return ans; }
bool SLayoutSize::valueEqual(float value) { return fequal(fSize,value); }
void ApertureConfiguration::ConfigureElementApertures(AcceleratorModel* Model) { //Get a list of all elements std::vector<AcceleratorComponent*> Elements; int nElements = Model->ExtractTypedElements(Elements,"*"); std::cout << "Got " << nElements << " elements for aperture configuration" << std::endl; std::cout << "Got " << ApertureList.size() << " Aperture entries" << std::endl; Aperture* aper; /** * Elements - The container with all AcceleratorComponent entries * comp - Iterator to all AcceleratorComponent entries * * ApertureList - The container with all Aperture entries * itr - Iterator to all Aperture entries. * * ThisElementAperture - The container for the current element Aperture. */ for(std::vector<AcceleratorComponent*>::iterator comp = Elements.begin(); comp!=Elements.end(); comp++) { if((*comp)->GetAperture() == nullptr) { double ElementLength = (*comp)->GetLength(); double Position = (*comp)->GetComponentLatticePosition(); /** * Give magnets and other fixed elements a set aperture. * Give drifts interpolated apertures. */ //Get the Type of Element this is. std::string ElementType = (*comp)->GetType(); //We only care about non-zero length elements if(ElementLength != 0) { //For all elements that are not drifts, set a fixed (non-interpolated) aperture type. if(ElementType != "Drift") { //std::cout << (*comp)->GetQualifiedName() << " run" << std::endl; //Loop over all aperture entries for(std::vector<ap>::iterator itr = ApertureList.begin(); itr!=ApertureList.end(); itr++) { //If the aperture entry is > the element start position and less than the exit //if(( itr->s >= Position && itr->s <= (Position + ElementLength) ) || fequal(itr->s, (Position + ElementLength),1e-6) ) //if(( itr->s >= Position) || fequal(itr->s, (Position + ElementLength),1e-6) ) if( itr->s >= Position ) { // std::cout << (*comp)->GetQualifiedName() << " hit" << std::endl; //Add the appropriate aperture type if(itr->ApType == RECTELLIPSE || itr->ApType == LHCSCREEN) { aper = new RectEllipseAperture(itr->ap1, itr->ap2, itr->ap3, itr->ap4); } else if(itr->ApType == CIRCLE) { aper = new CircularAperture(itr->ap1); } else if(itr->ApType == ELLIPSE) { aper = new EllipticalAperture(itr->ap1, itr->ap2); } else if(itr->ApType == RECTANGLE) { aper = new RectangularAperture(itr->ap1, itr->ap2); } else { std::cerr << (*comp)->GetQualifiedName() << " aperture Class bug" << std::endl; exit(EXIT_FAILURE); } (*comp)->SetAperture(aper); itr=ApertureList.end(); break; } if(itr==ApertureList.end()) { std::cerr << (*comp)->GetQualifiedName() << " hit end" << std::endl; } } }//End of fixed elements else //Deal with drifts { //std::cout << (*comp)->GetQualifiedName() << std::endl; //Loop over all aperture entries for(std::vector<ap>::iterator itr = ApertureList.begin(); itr!=ApertureList.end(); itr++) { //If the aperture entry is >= the element position //or if we have reach the end of the aperture entries i.e. the left overs at the end of the ring past the last marker if(itr->s >= Position || itr==(ApertureList.end()-1)) { /** * 3 possible cases * 1: First entry in the element (or accelerator) * 2: Entries within an element * 3: Final entry within an element (or accelerator) */ std::vector<ap> ThisElementAperture; //Deal with the first entry for this element if(itr == ApertureList.begin()) { std::cout << "At first element " << (*comp)->GetQualifiedName() << " getting aperture iterpolation from last element" << std::endl; //got the initial point itr = ApertureList.end()-1; ap tempAp; tempAp.s = 0; tempAp.ap1 = itr->ap1; tempAp.ap2 = itr->ap2; tempAp.ap3 = itr->ap3; tempAp.ap4 = itr->ap4; tempAp.ApType = itr->ApType; //record ap points ThisElementAperture.push_back(tempAp); //go back to where we were itr = ApertureList.begin(); } else { //get the previous point before this element itr--; //record ap points ThisElementAperture.push_back(*itr); //go back to where we were itr++; } //Now add in all entries that exist within the length of the element while(itr->s <= (Position + ElementLength) ) //while(itr->s <= (Position + ElementLength)) { ThisElementAperture.push_back(*itr); //Increment the iterator to the next entry itr++; if(itr == ApertureList.end()) { break; } } //Deal with the very last element entry if(itr == ApertureList.end()) { std::cout << "At last element " << (*comp)->GetQualifiedName() << " getting aperture iterpolation from first element" << std::endl; itr = ApertureList.begin(); ap tempAp; tempAp.s = ElementLength + Position; tempAp.ap1 = itr->ap1; tempAp.ap2 = itr->ap2; tempAp.ap3 = itr->ap3; tempAp.ap4 = itr->ap4; tempAp.ApType = itr->ApType; ThisElementAperture.push_back(tempAp); } else { ThisElementAperture.push_back(*itr); itr = ApertureList.end(); } /** * Now move on to assigning the correct type of aperture. */ bool ZeroEntry = false; size_t NegativeCount = 0; //First do a little bit of cleaning //If we have an entry at 0 (or very close to), and also an entry at negative values, we can discard the negative entry for(size_t itAp = 0; itAp < ThisElementAperture.size(); itAp++) { if( fequal(ThisElementAperture[itAp].s - Position, 0.0, 1e-7) ) { ZeroEntry = true; ThisElementAperture[itAp].s = Position; } if( ThisElementAperture[itAp].s - Position < 0 ) { NegativeCount++; } } if(NegativeCount!=0 && ZeroEntry) { //Delete the first entry (negative) ThisElementAperture.erase(ThisElementAperture.begin()); NegativeCount--; } while(NegativeCount > 1 ) { //Delete the first entry (negative) ThisElementAperture.erase(ThisElementAperture.begin()); NegativeCount--; } if( fequal(ThisElementAperture[0].s - Position, 0.0, 5e-7) ) { ThisElementAperture[0].s = Position; } /** * Check if all values are constant */ bool ap1=true,ap2=true,ap3=true,ap4=true,circle=true; double ap1p=0,ap2p=0,ap3p=0,ap4p=0; bool ApTypeChange = false; ApertureClass_t ApTypeToAdd; for(size_t itap = 0; itap < ThisElementAperture.size(); itap++) { //configure for first pass if(itap == 0) { ap1p = ThisElementAperture[itap].ap1; ap2p = ThisElementAperture[itap].ap2; ap3p = ThisElementAperture[itap].ap3; ap4p = ThisElementAperture[itap].ap4; ApTypeToAdd = ThisElementAperture[itap].ApType; } else { //now check which elements are the same each pass if(ThisElementAperture[itap].ap1 != ap1p) { ap1 = false; } if(ThisElementAperture[itap].ap2 != ap2p) { ap2 = false; } if(ThisElementAperture[itap].ap3 != ap3p) { ap3 = false; } if(ThisElementAperture[itap].ap4 != ap4p) { ap4 = false; } if(ThisElementAperture[itap].ApType != ApTypeToAdd) { ApTypeChange = true; } } } bool Interpolated = false; if(ap1 == false || ap2 == false || ap3 == false || ap4 == false) { Interpolated = true; } if(Interpolated) { InterpolatedAperture* apInterpolated = new InterpolatedAperture(); for(size_t n=0; n < ThisElementAperture.size(); n++ ) { //ThisElementAperture[n].s -= Position; apInterpolated->ApertureEntry.s = ThisElementAperture[n].s - Position; apInterpolated->ApertureEntry.ap1 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap2 = ThisElementAperture[n].ap2; apInterpolated->ApertureEntry.ap3 = ThisElementAperture[n].ap3; apInterpolated->ApertureEntry.ap4 = ThisElementAperture[n].ap4; apInterpolated->ApertureList.push_back(apInterpolated->ApertureEntry); } //Check we have a constant aperture type if(ApTypeChange == false) { if(ApTypeToAdd == CIRCLE) { aper = new InterpolatedCircularAperture(apInterpolated->GetApertureList()); } else if(ApTypeToAdd == RECTANGLE) { std::cerr << "TODO: Add a InterpolatedRectangularAperture Class" << std::endl; exit(EXIT_FAILURE); // aper = new InterpolatedRectangularAperture(apInterpolated->GetApertureList()); } else if(ApTypeToAdd == ELLIPSE) { aper = new InterpolatedEllipticalAperture(apInterpolated->GetApertureList()); } else if(ApTypeToAdd == RECTELLIPSE || ApTypeToAdd == LHCSCREEN) { aper = new InterpolatedRectEllipseAperture(apInterpolated->GetApertureList()); } else { std::cerr << "Drift: constant aperture Class bug" << std::endl; exit(EXIT_FAILURE); } (*comp)->SetAperture(aper); itr = ApertureList.end(); break; } else //We have a change in aperture type. Assume rectellipse for now { //This should work for changes between circles/ellipses/rectellipse //Just set the missing coordinates to the same size as the known parameters for rectellipse InterpolatedAperture* apInterpolated = new InterpolatedAperture(); for(size_t n=0; n < ThisElementAperture.size(); n++ ) { ThisElementAperture[n].s -= Position; apInterpolated->ApertureEntry.s = ThisElementAperture[n].s; if(ThisElementAperture[n].ApType == RECTELLIPSE) { apInterpolated->ApertureEntry.ap1 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap2 = ThisElementAperture[n].ap2; apInterpolated->ApertureEntry.ap3 = ThisElementAperture[n].ap3; apInterpolated->ApertureEntry.ap4 = ThisElementAperture[n].ap4; } else if(ThisElementAperture[n].ApType == CIRCLE) { apInterpolated->ApertureEntry.ap1 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap2 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap3 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap4 = ThisElementAperture[n].ap1; } else if(ThisElementAperture[n].ApType == ELLIPSE) { apInterpolated->ApertureEntry.ap1 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap2 = ThisElementAperture[n].ap2; apInterpolated->ApertureEntry.ap3 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap4 = ThisElementAperture[n].ap2; } else if(ThisElementAperture[n].ApType == RECTANGLE) { apInterpolated->ApertureEntry.ap1 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap2 = ThisElementAperture[n].ap2; apInterpolated->ApertureEntry.ap3 = ThisElementAperture[n].ap1; apInterpolated->ApertureEntry.ap4 = ThisElementAperture[n].ap2; } else { std::cerr << "Drift: interpolated aperture Class bug" << std::endl; exit(EXIT_FAILURE); } apInterpolated->ApertureList.push_back(apInterpolated->ApertureEntry); } aper = new InterpolatedRectEllipseAperture(apInterpolated->GetApertureList()); (*comp)->SetAperture(aper); itr = ApertureList.end(); break; } } else //constant aperture drift, operate as for magnets { if(ApTypeToAdd == RECTELLIPSE || ApTypeToAdd == LHCSCREEN) { aper = new RectEllipseAperture(ap1p, ap2p, ap3p, ap4p); } else if(ApTypeToAdd == CIRCLE) { aper = new CircularAperture(ap1p); } else if(ApTypeToAdd == ELLIPSE) { aper = new EllipticalAperture(ap1p, ap2p); } else if(ApTypeToAdd == RECTANGLE) { aper = new RectangularAperture(ap1p, ap2p); } (*comp)->SetAperture(aper); itr = ApertureList.end(); break; } } } }//End of drifts } } if(logFlag) { *log << std::setw(25) << std::left << (*comp)->GetName(); *log << std::setw(14) << std::left << (*comp)->GetType(); *log << std::setw(10) << std::left << (*comp)->GetLength(); *log << std::setw(10) << std::left << (*comp)->GetComponentLatticePosition(); if ((*comp)->GetAperture() != nullptr) { (*comp)->GetAperture()->printout(*log); } *log << endl; } } }
bool SLayoutSize::isZero() const { return fequal(fSize, 0.0f); }
bool SLayoutSize::isValid() const { return !fequal(fSize,SIZE_UNDEF); }
// Treating Ray r as the ray from the camera glm::vec3 Integrator::DirectLightingIntegratorTraceRay(Ray &r, unsigned int depth, float ¤t_brdf_PDF, glm::vec3 ¤t_BxDFCol_Dot) { bool is_BVH = true; float light_PDF, BxDF_PDF; //probability distribution functions for light and material float light_importance, bxdf_importance; glm::vec3 light_incoming, LTE_LIGHT, LTE_BxDF; r.origin = r.origin + 0.0001f * r.direction; // avoid shadow acne from floats Intersection isx; if(is_BVH) { isx = intersection_engine->IntersectionByBounds(r, intersection_engine->root); } else { isx = intersection_engine->GetIntersection(r); } // Sample a random point on a random light Geometry* rand_light = scene->lights.at(qrand() % scene->lights.size()); Intersection sample_isx = rand_light->GetSamplePoint(isx.normal); // If object no object is hit then return black // If object hit is a light, return its texturecolor * basecolor if (isx.object_hit == NULL) { current_brdf_PDF = -1; // this ends the trace return glm::vec3(0.0f); } else if (isx.object_hit->material->is_light_source) { current_brdf_PDF = -1; // this ends the trace return isx.texture_color * isx.object_hit->material->base_color; } // RAY CONVENTION // All rays are pointing away from the geometry // wj = Ray from geometry to the light glm::vec3 wj_dir = glm::normalize(sample_isx.point - isx.point); Ray wj = Ray(isx.point + wj_dir * 0.0001f, wj_dir); // wo is the ray from the object to the camera in the first iteration // wo is otherwise the old wj reversed glm::vec3 wo = -r.direction; // get material properties of intersection BxDF* BxDF_RAND = isx.object_hit->material->GetRandomBxDF(); /** * Light Sampling **/ // Direct lighting test Intersection obs_isx; if(is_BVH) { obs_isx = intersection_engine->IntersectionByBounds(Ray(wj.origin + 0.001f * wj.direction, wj.direction), intersection_engine->root); } else { obs_isx = intersection_engine->GetIntersection(Ray(wj.origin + 0.001f * wj.direction, wj.direction)); } if (obs_isx.object_hit != rand_light) { light_incoming = glm::vec3(0.0f); // radiance light_PDF = 0.f; } else { // hit rand_light // Calculate the LightESE light_incoming = rand_light->material->EvaluateScatteredEnergy(sample_isx, wo, -wj.direction, BxDF_RAND); // light_PDF tells us if the light hit it light_PDF = obs_isx.object_hit->RayPDF(obs_isx, wj); // if no light hit it return 0 if (light_PDF <= 0.0001f) { light_PDF = 0.f; light_incoming = glm::vec3(0.0f); } } // Convert to Normal Space to pass into the PDF function for BxDF // Refactor? glm::mat3 T = glm::mat3(isx.tangent, isx.bitangent, isx.normal); T = glm::transpose(T); glm::vec3 pdf_wi = T * wj.direction; glm::vec3 pdf_wo = T * wo; // Calculate the BxDF_PDF BxDF_PDF = BxDF_RAND->PDF(pdf_wo, pdf_wi); float dot_wj_nor = glm::abs(glm::dot(wj.direction, isx.normal)); // Calculate weighting for the materials. glm::vec3 BRDF_color = isx.object_hit->material->EvaluateScatteredEnergy(isx, wo, wj.direction, BxDF_RAND); // First Half of the Equation if (fequal(light_PDF, 0.f)) { LTE_LIGHT = glm::vec3(0.0f); // Set MIS to 0 mostly because if BxDF_PDF is also 0 then it would be NaN // If light_PDF is 0, then MIS should be zero anyway light_importance = 0.f; } else { LTE_LIGHT = BRDF_color * light_incoming * dot_wj_nor / light_PDF; light_importance = light_PDF * light_PDF / (light_PDF * light_PDF + BxDF_PDF * BxDF_PDF); } // Sample a ray from the bxdf and get the color for indirect lighting BRDF_color = isx.object_hit->material->SampleAndEvaluateScatteredEnergy(isx, wo, wj.direction, BxDF_PDF, BxDF_RAND); if (BxDF_PDF <= 0.f) { BRDF_color = glm::vec3(0.f); } dot_wj_nor = glm::abs(glm::dot(wj.direction, isx.normal)); if (fequal(BxDF_PDF, 0.0f)) { LTE_BxDF = glm::vec3(0.0f); // Set MIS to 0 mostly because if BxDF_PDF is also 0 then it would be NaN // If BxDF_PDF is 0, then MIS should be zero anyway bxdf_importance = 0.f; } else { LTE_BxDF = BRDF_color * light_incoming * dot_wj_nor / BxDF_PDF; bxdf_importance = BxDF_PDF * BxDF_PDF / (light_PDF * light_PDF + BxDF_PDF * BxDF_PDF); } // Multiple importance sampling for returned luminosity glm::vec3 LTE = light_importance * LTE_LIGHT + bxdf_importance * LTE_BxDF; // Update references for continuing along path r = wj; // next path ray current_brdf_PDF = BxDF_PDF; // for roulette weight current_BxDFCol_Dot = BRDF_color * dot_wj_nor; // for weighting color of next iterations return LTE; }
/***************************************************************************** Function name: SolarAngle() Purpose : this subroutine uses solar radiation measured on a horizontal surface to calculate direct, diffuse, and incoming reflected solar radiation for a sloping surface. Required : float Latitude - site laditude (rad) float Albedo - surface Albedo float Declination - solar Declination (rad) float CellAspect - cell aspect (rads eastward from north) float CellSlope - ground surface slope (rads) float SineSolarAltitude - sine of sun's SolarAltitudede float SunMax - calculated solar radiation at the top of the atmosphere (W/m^2) float SolarTimeStep - fraction of the timestep the sun is above the horizon int DayLight - FALSE: measured solar radiation and the sun is below the horizon. TRUE: sun is above the horizon float SolarAzimuth - solar azimuth (rads eastward from north) float Dt - length of current timestep (hr) Returns : void Modifies : float *Direct - direct beam solar radiation (W/m^2) float *Diffuse - diffuse solar radiation (W/m^2) Comments : EXECUTE EACH TIMESTEP FOR EACH GRID CELL Source: Gates, D.M., "Biophysical ecology", Springer-Verlag, New York, etc., 1980. Especially Chapter 6, p. 136 -> *****************************************************************************/ void SolarAngle(float Latitude, float Albedo, float Declination, float CellAspect, float CellSlope, float SunMax, float SineSolarAltitude, float SolarTimeStep, int DayLight, float SolarAzimuth, float Dt, float *Direct, float *Diffuse) { float SolarAltitude; /* SolarAltitude of sun from horizon (rads) */ float CosineIncidenceAngle; /* cosine of the incidence angle between solar rays and the normal to the surface */ float DiffuseSkyView; /* sky view factor for diffuse radation (0.0 - 1.0) */ float ReflectedSkyView; /* view factor for incoming refected solar radiation (0.0 - 1.0) */ float Reflect; /* incoming reflected solar radiation (W/m^2) */ /* NOTE THAT HERE Dt IS IN HOURS, NOT IN SECONDS */ if (DayLight == TRUE) { /* calculate shortwave components horizontal surface */ if (fequal(CellSlope, 0.0)) { *Direct = SunMax; *Diffuse = SunMax; Reflect = 0.0; } else { /* sloping surface */ DiffuseSkyView = (PI - CellSlope) / PI; ReflectedSkyView = CellSlope / PI; SolarAltitude = asin(SineSolarAltitude); CosineIncidenceAngle = cos(SolarAltitude) * sin(CellSlope) * cos(SolarAzimuth - CellAspect) + cos(CellSlope) * sin(SolarAltitude); *Direct = SunMax * CosineIncidenceAngle / SineSolarAltitude; if (CosineIncidenceAngle <= 0.0) *Direct = 0.0; *Diffuse = SunMax * DiffuseSkyView; Reflect = Albedo * SunMax * ReflectedSkyView; } /* end sloping surface */ } /* end daylight is true */ else { /* sun is below the horizon */ /* all measured solar radiation is diffuse, thus total rad on CellSlope is (measured)*DiffuseSkyView */ *Direct = 0.0; Reflect = 0.0; *Diffuse = (PI - CellSlope) / PI; } /* Average over timestep */ if (Dt > 0.0) { /* The assumption is made that the incoming reflected radiation is diffuse radiation for the "receiving" gridcell */ *Diffuse += Reflect; *Direct *= SolarTimeStep / (Dt * RADPHOUR); *Diffuse *= SolarTimeStep / (Dt * RADPHOUR); } }
bool mp_potential_path_object(int path, const double x, const double y, const double stepsize, double factor, const int object, const bool solid_only) { enigma::object_collisions* const inst = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); double pathpx = inst->x, pathpy = inst->y, pathpdir = inst->direction; path_clear_points(path); path_add_point(path, pathpx, pathpy, 100); if (fequal(pathpx, x) && fequal(pathpy, y)) return true; if (factor < 1) return false; double dir, xstep, ystep, goaldir; bool pathfound; const double max_dist = factor*hypot(x - pathpx, y - pathpy); while (path_get_length(path) < max_dist) { goaldir = atan2(pathpy - y, x - pathpx)*(180/M_PI); pathfound = false; //direct goal direction dir = (goaldir + 360) %(variant) 360; if (abs((dir - pathpdir + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { if (hypot(x - pathpx, y - pathpy) <= stepsize) { if (solid_only ? (place_free(x, y)) : (!place_meeting(x, y, object))) { path_add_point(path, x, y, 100); return true; } return false; } xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep) && place_free(pathpx + xstep, pathpy + ystep)) : (!place_meeting(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep, object) && !place_meeting(pathpx + xstep, pathpy + ystep, object))) { pathpdir = dir; pathpx += xstep; pathpy += ystep; path_add_point(path, pathpx, pathpy, 100); pathfound = true; } } if (!pathfound) { //alternate either side of the goal direction full circle for (int i = mp_potential::rotstep; i < 180; i += mp_potential::rotstep) { dir = (goaldir - i + 360) %(variant) 360; if (abs((dir - pathpdir + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep) && place_free(pathpx + xstep, pathpy + ystep)) : (!place_meeting(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep, object) && !place_meeting(pathpx + xstep, pathpy + ystep, object))) { pathpdir = dir; pathpx += xstep; pathpy += ystep; path_add_point(path, pathpx, pathpy, 100); pathfound = true; break; } } dir = (goaldir + i + 360) %(variant) 360; if (abs((dir - pathpdir + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep) && place_free(pathpx + xstep, pathpy + ystep)) : (!place_meeting(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep, object) && !place_meeting(pathpx + xstep, pathpy + ystep, object))) { pathpdir = dir; pathpx += xstep; pathpy += ystep; path_add_point(path, pathpx, pathpy, 100); pathfound = true; break; } } } if (!pathfound) return false; } } return false; }
bool SLayoutSize::isMatchParent() const { return fequal(fSize , SIZE_MATCH_PARENT); }
bool mp_potential_step_object(const double x, const double y, const double stepsize, const int object, const bool solid_only) { enigma::object_collisions* const inst = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); if (fequal(inst->x, x) && fequal(inst->y, y)) return true; double dir, xstep, ystep, goaldir; goaldir = atan2(inst->y - y, x - inst->x)*(180/M_PI); dir = (goaldir + 360) %(variant) 360; //direct goal direction if (abs((dir - inst->direction + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { if (hypot(x - inst->x, y - inst->y) <= stepsize) { if (solid_only ? (place_free(x, y)) : (!place_meeting(x, y, object))) { inst->direction = dir; inst->x = x; inst->y = y; return true; } if (mp_potential::onspot) { inst->direction += min(mp_potential::maxrot, max(-mp_potential::maxrot, (goaldir - inst->direction + 540) %(variant) 360 - 180)); } return false; } xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(inst->x + mp_potential::ahead*xstep, y + mp_potential::ahead*ystep) && place_free(inst->x + xstep,inst->y + ystep)) : (!place_meeting(inst->x + mp_potential::ahead*xstep, y + mp_potential::ahead*ystep, object) && !place_meeting(inst->x + xstep, inst->y + ystep, object))) { inst->direction = dir; inst->x += xstep; inst->y += ystep; return true; } } //alternate either side of the goal direction full circle for (int i = mp_potential::rotstep; i < 180; i += mp_potential::rotstep) { dir = (goaldir - i + 360) %(variant) 360; if (abs((dir - inst->direction + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(inst->x + mp_potential::ahead*xstep, y + mp_potential::ahead*ystep) && place_free(inst->x + xstep,inst->y + ystep)) : (!place_meeting(inst->x + mp_potential::ahead*xstep, y + mp_potential::ahead*ystep, object) && !place_meeting(inst->x + xstep, inst->y + ystep, object))) { inst->direction = dir; inst->x += xstep; inst->y += ystep; return true; } } dir = (goaldir + i + 360) %(variant) 360; if (abs((dir - inst->direction + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(inst->x + mp_potential::ahead*xstep, inst->y + mp_potential::ahead*ystep) && place_free(inst->x + xstep, inst->y + ystep)) : (!place_meeting(inst->x + mp_potential::ahead*xstep, inst->y + mp_potential::ahead*ystep, object) && !place_meeting(inst->x + xstep, inst->y + ystep, object))) { inst->direction = dir; inst->x += xstep; inst->y += ystep; return true; } } } if (mp_potential::onspot) { inst->direction += min(mp_potential::maxrot, max(-mp_potential::maxrot, (goaldir - inst->direction + 540) %(variant) 360 - 180)); } return false; }
void CSnowInterception::init(int y, int x, int Dt, float F, float LAI, float MaxInt, float MaxSnowIntCap, float MDRatio, float SnowIntEff, float Ra, float AirDens, float EactAir, float Lv, PIXRAD * LocalRad, float Press, float Tair, float Vpd, float Wind, float *RainFall, float *SnowFall, float *IntRain, float *IntSnow, float *TempIntStorage, float *VaporMassFlux, float *Tcanopy, float *MeltEnergy, float *MomentSq, float *Height, unsigned char Understory, float MS_Rainfall, float LD_FallVelocity) { float AdvectedEnergy; /* Energy advected by the rain (W/m2) */ float DeltaSnowInt; /* Change in the physical swe of snow interceped on the branches. (m) */ float Drip; /* Amount of drip from intercepted snow as a result of snowmelt (m) */ float ExcessSnowMelt; /* Snowmelt in excess of the water holding capacity of the tree (m) */ float EsSnow; /* saturated vapor pressure in the snow pack (Pa) */ float InitialSnowInt; /* Initial intercepted snow (m) */ float InitialWaterInt; /* Initial intercepted water (snow and rain) (m) */ float LatentHeat; /* Latent heat flux (W/m2) */ float LongOut; /* Longwave radiation emitted by canopy (W/m2) */ float Ls; /* Latent heat of sublimation (J/(kg K) */ float MassBalanceError; /* Mass blalnce to make sure no water is being destroyed/created (m) */ float MaxWaterInt; /* Water interception capacity (m) */ float MaxSnowInt; /* Snow interception capacity (m) - multiplier w/ temp */ float NetRadiation; float PotSnowMelt; /* Potential snow melt (m) */ float RainThroughFall; /* Amount of rain reaching to the ground (m) */ float RefreezeEnergy; /* Energy available for refreezing or melt */ float ReleasedMass; /* Amount of mass release of intercepted snow (m) */ float SensibleHeat; /* Sensible heat flux (W/m2) */ float SnowThroughFall; /* Amount of snow reaching to the ground (m) */ float Tmp; /* Temporary variable */ float MaxIntercept; /* max snow interception - regardless of temp */ float overload; /* overload of intercepted snow due to rainfall or condensation */ float intrainfrac; /* fraction of intercepted water which is liquid */ float intsnowfrac; /*fraction of intercepted water which is solid */ float OriginalRainfall; /* Initialize Drip, H2O balance, and mass release variables. */ OriginalRainfall = *RainFall; InitialWaterInt = *IntSnow + *IntRain; *IntSnow /= F; *IntRain /= F; InitialSnowInt = *IntSnow; Drip = 0.0; ReleasedMass = 0.0; /* Determine the maximum snow interception water equivalent. Kobayashi, D., 1986, Snow Accumulation on a Narrow Board, Cold Regions Science and Technology, (13), pp. 239-245. Figure 4. */ if (Tair > -5.0) MaxSnowInt = 1.0; else MaxSnowInt = 0.25; /* therefore LAI_ratio decreases as temp decreases */ MaxSnowInt *= MaxSnowIntCap; MaxIntercept = MaxSnowIntCap; /* Calculate snow interception. */ DeltaSnowInt = SnowIntEff * *SnowFall; if (DeltaSnowInt + *IntSnow > MaxSnowInt) DeltaSnowInt = MaxSnowInt - *IntSnow; if (DeltaSnowInt < 0.0) DeltaSnowInt = 0.0; /* now update snowfall and total accumulated intercepted snow amounts */ /* pixel depth */ SnowThroughFall = (*SnowFall - DeltaSnowInt) * F + (*SnowFall) * (1 - F); /* physical depth */ *IntSnow += DeltaSnowInt; /* Calculate amount of rain intercepted on branches and stored in intercepted snow. */ /* physical depth */ MaxWaterInt = LIQUID_WATER_CAPACITY * (*IntSnow) + MaxInt; if ((*IntRain + *RainFall) <= MaxWaterInt) { /* physical depth */ *IntRain += *RainFall; /* pixel depth */ RainThroughFall = *RainFall * (1 - F); } else { /* pixel depth */ RainThroughFall = (*IntRain + *RainFall - MaxWaterInt) * F + (*RainFall * (1 - F)); /* physical depth */ *IntRain = MaxWaterInt; } /* Now that total intercepted water has been calculated, allow for structural unloading of branches. I.e. if absolute maximum capacity is reached then allow sliding due to branch bending. Of course, if chunks of snow are falling, they can contain both ice and liquid water - Let both of these come off in the correct proportions */ if (*IntRain + *IntSnow > MaxIntercept) { overload = (*IntRain + *IntSnow) - MaxIntercept; intsnowfrac = *IntSnow / (*IntSnow + *IntRain); intrainfrac = *IntRain / (*IntSnow + *IntRain); *IntRain = *IntRain - overload * intrainfrac; *IntSnow = *IntSnow - overload * intsnowfrac; SnowThroughFall = SnowThroughFall + overload * intsnowfrac * F; RainThroughFall = RainThroughFall + overload * intrainfrac * F; } /* The canopy temperature is assumed to be equal to the air temperature if the air temperature is below 0C, otherwise the canopy temperature is equal to 0C */ if (Tair > 0.) *Tcanopy = 0.; else *Tcanopy = Tair; /* Calculate the net radiation at the canopy surface, using the canopy temperature. The outgoing longwave is subtracted twice, because the canopy radiates in two directions */ Tmp = *Tcanopy + 273.15; LongOut = STEFAN * (Tmp * Tmp * Tmp * Tmp); NetRadiation = LocalRad->NetShort[0] + LocalRad->LongIn[0] - 2 * F * LongOut; NetRadiation /= F; /* Calculate the vapor mass flux between the canopy and the surrounding air mass - snow covered aerodynamic resistance is assumed to increase by an order of magnitude based on Lunderg et al 1998, Journal of Hydrological Processes */ EsSnow = SatVaporPressure(*Tcanopy); *VaporMassFlux = AirDens * (EPS / Press) * (EactAir - EsSnow) / (Ra * 10.0); *VaporMassFlux /= WATER_DENSITY; if (fequal(Vpd, 0.0) && *VaporMassFlux < 0.0) *VaporMassFlux = 0.0; /* Calculate the latent heat flux */ Ls = (677. - 0.07 * *Tcanopy) * JOULESPCAL * GRAMSPKG; LatentHeat = Ls * *VaporMassFlux * WATER_DENSITY; /* Calculate the sensible heat flux */ SensibleHeat = AirDens * CP * (Tair - *Tcanopy) / (Ra * 10.0); /* Calculate the advected energy */ AdvectedEnergy = (CH_WATER * Tair * *RainFall) / Dt; /* Calculate the amount of energy available for refreezing */ RefreezeEnergy = SensibleHeat + LatentHeat + NetRadiation + AdvectedEnergy; RefreezeEnergy *= Dt; /* if RefreezeEnergy is positive it means energy is available to melt the intercepted snow in the canopy. If it is negative, it means that intercepted water will be refrozen */ /* Update maximum water interception storage */ MaxWaterInt = LIQUID_WATER_CAPACITY * (*IntSnow) + MaxInt; /* Convert the vapor mass flux from a flux to a depth per interval */ *VaporMassFlux *= Dt; if (RefreezeEnergy > 0.0) { /*we've got melt */ if (-(*VaporMassFlux) > *IntRain) { *VaporMassFlux = -(*IntRain); *IntRain = 0.; } else *IntRain += *VaporMassFlux; PotSnowMelt = MIN((RefreezeEnergy / (LF * WATER_DENSITY)), *IntSnow); *MeltEnergy -= (LF * PotSnowMelt * WATER_DENSITY) / Dt; if ((*IntRain + PotSnowMelt) <= MaxWaterInt) { /* if the intercepted rain and potential snowmelt is less than the liquid water holding capacity of the intercepted snowpack, then simply add the total potential snowmelt to the liquid water content of the intercepted snowpack. */ *IntSnow -= PotSnowMelt; *IntRain += PotSnowMelt; PotSnowMelt = 0.0; } else { ExcessSnowMelt = PotSnowMelt + *IntRain - MaxWaterInt; *IntSnow -= MaxWaterInt - (*IntRain); *IntRain = MaxWaterInt; if (*IntSnow < 0.0) *IntSnow = 0.0; if (SnowThroughFall > 0.0 && InitialSnowInt <= MIN_INTERCEPTION_STORAGE) { /* Water in excess of MaxWaterInt has been generated. If it is snowing and there was little intercepted snow at the beginning of the time step ( <= MIN_INTERCEPTION_STORAGE), then allow the snow to melt as it is intercepted. Also, enforce that the following holds true: if Intercpeted snow is below minimum thresold then it can only be removed via melting */ Drip += ExcessSnowMelt; *IntSnow -= ExcessSnowMelt; if (*IntSnow < 0.0) *IntSnow = 0.0; ExcessSnowMelt = 0.0; } else /* Else, SnowThroughFall = 0.0 or SnowThroughFall > 0.0 and there is a substantial amount of intercepted snow at the beginning of the time step ( > MIN_INTERCEPTION_STORAGE). Snow melt may generate mass release. */ *TempIntStorage += ExcessSnowMelt; MassRelease(IntSnow, TempIntStorage, &ReleasedMass, &Drip, MDRatio); } /* If intercepted snow has melted, add the water it held to drip */ MaxWaterInt = LIQUID_WATER_CAPACITY * (*IntSnow) + MaxInt; if (*IntRain > MaxWaterInt) { Drip += *IntRain - MaxWaterInt; *IntRain = MaxWaterInt; } } else { /* else (RefreezeEnergy <= 0.0) */ /* Reset *TempIntStorage to 0.0 when energy balance is negative */ *TempIntStorage = 0.0; /* Refreeze as much surface water as you can */ if (RefreezeEnergy > -(*IntRain) * LF) { *IntSnow += fabs(RefreezeEnergy) / LF; *IntRain -= fabs(RefreezeEnergy) / LF; *MeltEnergy += (fabs(RefreezeEnergy) * WATER_DENSITY) / Dt; RefreezeEnergy = 0.0; } else { /* All of the water in the surface layer has been frozen. */ *IntSnow += *IntRain; /* Added on April 8 as a test */ /* RefreezeEnergy += *IntRain*LF; */ /* *VaporMassFlux = MAX(*VaporMassFlux, */ /* RefreezeEnergy/(Ls * WATER_DENSITY)); */ /* Energy released by freezing of intercepted water is added to the MeltEnergy */ *MeltEnergy += (LF * *IntRain * WATER_DENSITY) / Dt; *IntRain = 0.0; } if (-(*VaporMassFlux) > *IntSnow) { *VaporMassFlux = -(*IntSnow); *IntSnow = 0.0; } else *IntSnow += *VaporMassFlux; } /* Convert drip, mass, *IntSnow, *IntRain, *MeltEnergy and *int_vapor_flux from physical depths to pixel depths. Update p0 and snow_fract. */ *IntSnow *= F; *IntRain *= F; *MeltEnergy *= F; *VaporMassFlux *= F; Drip *= F; ReleasedMass *= F; /* Calculate intercepted H2O balance. */ MassBalanceError = (InitialWaterInt - (*IntSnow + *IntRain)) + (*SnowFall + *RainFall) - (SnowThroughFall + RainThroughFall + Drip + ReleasedMass) + *VaporMassFlux; *RainFall = RainThroughFall + Drip; *SnowFall = SnowThroughFall + ReleasedMass; /* Find momentum squared of rainfall for use by the sediment model. */ if(Understory) /* Since the understory is assumed to cover the entire grid cell, all momentum is associated with leaf drip, eq. 2, Wicks and Bathurst (1996) */ *MomentSq = pow(LD_FallVelocity * WATER_DENSITY, 2) * PI/6 * pow(LEAF_DRIP_DIA, 3) * (*RainFall)/Dt; else /* If no understory, part of the rainfall reaches the ground as direct throughfall. */ *MomentSq = pow(LD_FallVelocity * WATER_DENSITY, 2) * PI/6 * pow(LEAF_DRIP_DIA, 3) * Drip/Dt + (1-F) * MS_Rainfall; }
bool SLayoutSize::isWrapContent() const { return fequal(fSize , SIZE_WRAP_CONTENT); }