//recursive function void World::trace_scene(Scene_info &info, Directional_ray &ray, Directional_ray &spec_light, int rec_ctr, int cur_obj_idx, float min_distance, int i, int j, Vector3d &amb_dir, float factor, Point3d &cur_orig) { if(rec_ctr <= 0) return; for (int o = 0; o < _objects.size(); ++o){ if((o != cur_obj_idx)){//dont hit yourself again if( _tracer->hit(ray, _objects[o], info) ){ //get the color //lambertian shading //calculate the cos value if(_objects[o]->type() == obj_type::Triangle){ Triangle* cur_tri = reinterpret_cast<Triangle*>(_objects[o]); Vector3d tri_normal = cur_tri->get_n(); update_color(info, i, j, tri_normal, amb_dir, 1.f); } else if(_objects[o]->type() == obj_type::Sphere){//sphere Sphere* cur_sph = reinterpret_cast<Sphere*>(_objects[o]); Vector3d normal_hit = info._hit_point - cur_sph->center(); normal_hit.normalize_vector(); if(rec_ctr == MAX_RECURSE_NUM)//first time update_color(info, i, j, normal_hit, amb_dir, 1.f); else//average color update_color(info, i, j, normal_hit, amb_dir, factor); Directional_ray new_ray(ray); Scene_info new_info(info); update_dir_and_org(new_info, new_ray, normal_hit); trace_scene(new_info, new_ray, spec_light, (rec_ctr-1), o, min_distance, i, j, amb_dir, factor/2, cur_orig); //calaulate spec Vector3d view_vec = info._hit_point - cur_orig; view_vec.normalize_vector(); Directional_ray new_spec(spec_light); update_dir_and_org(new_info, new_spec, normal_hit); Vector3d spec_hit = new_spec.get_dir(); update_spec(info, i, j, spec_hit, view_vec, spec_light); } else { //simply copy the color copy_info_color(info, i, j); } } } } }
void tex::app_space () { ptr p, q; if (space_factor >= 2000 && xspace_skip != zero_glue) { q = new_param_glue(XSPACE_SKIP_CODE); } else { if (space_skip != zero_glue) { p = space_skip; } else { p = find_font_glue(cur_font); } p = new_spec(p); if (space_factor >= 2000) glue_width(p) += extra_space(cur_font); stretch(p) = xn_over_d(stretch(p), space_factor, 1000); shrink(p) = xn_over_d(shrink(p), 1000L, space_factor); q = new_glue(p); glue_ref_count(p) = 0; } tail_append(q); }
void tex::build_page () { int pi=0, b, c; ptr p, q, r; #define INF_SHRINK_PAGE "Infinite glue shrinkage found on current page" if (link(contrib_head) == null || output_active) return; do { p = link(contrib_head); if (last_glue != null) delete_glue_ref(last_glue); last_penalty = 0; last_kern = 0; if (type(p) == GLUE_NODE) { last_glue = glue_ptr(p); add_glue_ref(last_glue); } else { last_glue = null; if (type(p) == PENALTY_NODE) { last_penalty = penalty(p); } else if (type(p) == KERN_NODE) { last_kern = kern_width(p); } } switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: if (page_contents < BOX_THERE) { if (page_contents == EMPTY) { freeze_page_specs(BOX_THERE); } else { page_contents = BOX_THERE; } q = new_skip_param(TOP_SKIP_CODE); link(q) = p; link(contrib_head) = q; r = glue_ptr(q); if (glue_width(r) > box_height(p)) { glue_width(r) -= box_height(p); } else { glue_width(r) = 0; } continue; } else { page_total += page_depth + box_height(p); page_depth = box_depth(p); goto contribute; } case GLUE_NODE: if (page_contents < BOX_THERE) { goto done; } else if (precedes_break(page_tail)) { pi = 0; } else { goto update_heights; } break; case KERN_NODE: if (page_contents < BOX_THERE) { goto done; } else if (link(p) == null) { return; } else if (type(link(p)) == GLUE_NODE) { pi = 0; } else { goto update_heights; } break; case PENALTY_NODE: if (page_contents < BOX_THERE) { goto done; } else { pi = penalty(p); } break; case WHATSIT_NODE: goto contribute; case MARK_NODE: goto contribute; case INS_NODE: insert_page(p); goto contribute; default: confusion("page"); break; } if (pi < INF_PENALTY) { b = page_badness(); if (b < AWFUL_BAD) { if (pi <= EJECT_PENALTY) { c = pi; } else if (b < INF_BAD) { c = b + pi + insert_penalties; } else { c = DEPLORABLE; } } else { c = b; } if (insert_penalties >= 10000) c = AWFUL_BAD; if (tracing_pages > 0) show_page_stats(b, pi, c); if (c <= least_page_cost) { best_page_break = p; best_size = page_goal; least_page_cost = c; r = link(page_ins_head); while (r != page_ins_head) { best_ins_ptr(r) = last_ins_ptr(r); r = link(r); } } if (c == AWFUL_BAD || pi <= EJECT_PENALTY) { fire_up(p); if (output_active) return; continue; } } if (type(p) < GLUE_NODE || type(p) > KERN_NODE) { goto contribute; } update_heights: if (type(p) == KERN_NODE) { page_total += page_depth + kern_width(p); } else { q = glue_ptr(p); page_so_far[2 + stretch_order(q)] += stretch(q); page_shrink += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err(INF_SHRINK_PAGE); help_inf_shrink_page(); error(); r = new_spec(q); shrink_order(r) = NORMAL; delete_glue_ref(q); q = glue_ptr(p) = r; } page_total += page_depth + glue_width(q); } page_depth = 0; contribute: if (page_depth > page_max_depth) { page_total = page_total + page_depth - page_max_depth; page_depth = page_max_depth; } page_tail = link(page_tail) = p; link(contrib_head) = link(p); link(p) = null; continue; done: link(contrib_head) = link(p); link(p) = null; flush_node_list(p); } while (link(contrib_head) != null); if (nest_ptr == nest) { tail = contrib_head; } else { contrib_tail = contrib_head; } }
ptr tex::vert_break(ptr p, scal h, scal d) { int b; ptr q; ptr r; int t; int pi=0; ptr prev_p; scal prev_dp; ptr best_place=0; int least_cost; #define INF_SHRINK_BOX "Infinite glue shrinkage found in box being split" prev_p = p; least_cost = AWFUL_BAD; do_all_six(set_height_zero); prev_dp = 0; loop { if (p == null) { pi = EJECT_PENALTY; } else { switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: cur_height += prev_dp + box_height(p); prev_dp = box_depth(p); goto not_found; case WHATSIT_NODE: goto not_found; case GLUE_NODE: if (precedes_break(prev_p)) { pi = 0; } else { goto update_heights; } break; case KERN_NODE: if (link(p) == null) { t = PENALTY_NODE; } else { t = type(link(p)); } if (t == GLUE_NODE) { pi = 0; } else { goto update_heights; } break; case PENALTY_NODE: pi = penalty(p); break; case MARK_NODE: case INS_NODE: goto not_found; default: confusion("vertbreak"); } } if (pi < INF_PENALTY) { b = vert_badness(h); if (b < AWFUL_BAD) { if (pi <= EJECT_PENALTY) { b = pi; } else if (b < INF_BAD) { b += pi; } else { b = DEPLORABLE; } } if (b <= least_cost) { best_place = p; least_cost = b; best_height_plus_depth = cur_height + prev_dp; } if (b == AWFUL_BAD || pi <= EJECT_PENALTY) { return best_place; } } if (type(p) < GLUE_NODE || type(p) > KERN_NODE) { goto not_found; } update_heights: if (type(p) == KERN_NODE) { cur_height += prev_dp + kern_width(p); } else { q = glue_ptr(p); active_height[2 + stretch_order(q)] += stretch(q); active_height[6] += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err(INF_SHRINK_BOX); help_inf_shrink_box(); error(); r = new_spec(q); delete_glue_ref(q); shrink_order(r) = NORMAL; glue_ptr(p) = r; } cur_height += prev_dp + glue_width(q); } prev_dp = 0; not_found: if (prev_dp > d) { cur_height = cur_height + prev_dp - d; prev_dp = d; } prev_p = p; p = link(prev_p); } }