コード例 #1
0
ファイル: world.cpp プロジェクト: tigerzhua/Ray_trace_cpp
//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);
                    }
                }
            }
        }

}
コード例 #2
0
ファイル: eval.c プロジェクト: syntheticpp/cpptex
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);
	}
コード例 #3
0
ファイル: page.c プロジェクト: syntheticpp/cpptex
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;
	}
}
コード例 #4
0
ファイル: page.c プロジェクト: syntheticpp/cpptex
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);
	}
}