rgb_value_t Sphere::shade_reflective(Ray* ray, Light* light, std::list<Sphere*>* sphereList, coord_t* point, int ref_cnt){ rgb_value_t darkness, ret_val; darkness.r = 0; darkness.g = 0; darkness.b = 0; coord_t norm_vect; norm_vect = subtract_coord(point, ¢er); norm_vect = normalize_vect(&norm_vect); coord_t reflect_dir; reflect_dir = subtract_coord_nopt(ray->getDirection(), mult_vect(&norm_vect, 2.0*(scalar_mult_vect_nopt(norm_vect, ray->getDirection())))); if (ref_cnt > 0) { Ray* reflectedRay = new Ray(point, &reflect_dir); Sphere* pointer_dummy=this; ret_val = reflectedRay->raytrace(sphereList, light, &pointer_dummy, ref_cnt-1); delete reflectedRay; return ret_val; } else { return darkness; } }
rgb_value_t Sphere::shade_glass(Ray* ray, Light* light, std::list<Sphere*>* sphereList, coord_t* point, int ref_cnt){ rgb_value_t darkness, ret_val; darkness.r = 0; darkness.g = 0; darkness.b = 0; if (ref_cnt == 0) return darkness; coord_t norm_ray_dir_vect = ray->getDirection(); norm_ray_dir_vect = normalize_vect(&norm_ray_dir_vect); coord_t norm_vect; norm_vect = subtract_coord(point, ¢er); norm_vect = normalize_vect(&norm_vect); bool ray_going_inside = (scalar_mult_vect(&norm_vect, &norm_ray_dir_vect)<=0.0) ? true : false; coord_t refract_dir; float r, w, k; if (ray_going_inside) { r = 1/brechzahl; } else { r = brechzahl; } w = -scalar_mult_vect(&norm_vect, &norm_ray_dir_vect)*r; k = 1.0 + (w-r)*(w+r); if (k<0.0) { return this->shade_reflective(ray, light, sphereList, point, ref_cnt-1); } norm_ray_dir_vect = mult_vect(&norm_ray_dir_vect, r); norm_vect = mult_vect(&norm_vect, (w-sqrt(k))); refract_dir = add_coord(&norm_ray_dir_vect, &norm_vect); Ray* refractedRay = new Ray(point, &refract_dir); Sphere* pointer_dummy=this; ret_val = refractedRay->raytrace(sphereList, light, &pointer_dummy, ref_cnt-1); delete refractedRay; return ret_val; }
//physicsfuncs------------------------ void apply_forces(vect currentspeed, double mass, vect forces){ mult_vect(mass, forces); add_vect(forces, currentspeed); }
void friction_power(vect dst, vect currentspeed){ add_vect(currentspeed, dst); mult_vect(-1, dst); }
/* * Returns maximal element of m1 * m2. */ struct elem_pos_t* max_res_elem(struct matrix_t* m1, struct matrix_t* m2) { msize_t row, col; elem_t* restrict res; msize_t max_row, max_col; elem_t max_res; #ifndef NDEBUG max_row = max_col = -1; #endif max_res = MIN_ELEM; #ifndef NDEBUG print_matrix(m1); print_matrix(m2); #endif assert (m1->n_cols == m2->n_rows); /* Optimize for cache misses */ if ((m2 = transpose(m2)) == NULL) { return NULL; } if ((res = (elem_t*) _mm_malloc(sizeof(elem_t) * m1->n_rows * m2->n_rows, ELEM_ALIGN)) == NULL) { return NULL; } { msize_t m1_nrows, m2_nrows, m1_ncols; m1_nrows = m1->n_rows; m2_nrows = m2->n_rows; m1_ncols = m1->n_cols; /* no dependencies between iterations */ #pragma parallel for (row = 0; row < m1_nrows; row++) { #pragma parallel for (col = 0; col < m2_nrows; col++) { res[row * m2_nrows + col] = mult_vect(m1->data[row], m2->data[col], m1_ncols); } } for (row = 0; row < m1_nrows; row++) { for (col = 0; col < m2_nrows; col++) { if (res[row * m2_nrows + col] > max_res) { max_res = res[row * m2_nrows + col]; max_row = row; max_col = col; } } } } free_matrix(m2); _mm_free(res); assert ((max_row >= 0) && (max_col >= 0)); return elem_pos(max_row, max_col, max_res); }