Example #1
0
static void expandPerimeterFrom(map_t *m,TCOD_list_t perim,ray_data_t *r) {
	if ( r->xloc >= 0 ) {
		processRay(m,perim,new_ray(m,r->xloc+1,r->yloc),r);
	}
	if ( r->xloc <= 0 ) {
		processRay(m,perim,new_ray(m,r->xloc-1,r->yloc),r);
	}
	if ( r->yloc >= 0 ) {
		processRay(m,perim,new_ray(m,r->xloc,r->yloc+1),r);
	}
	if ( r->yloc <= 0 ) {
		processRay(m,perim,new_ray(m,r->xloc,r->yloc-1),r);
	}
}
Example #2
0
//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);
                    }
                }
            }
        }

}
Example #3
0
void		cast_ray(int x, int y, t_vec3f *pixel, t_interface *env)
{
	t_vec3f	dir;
	t_ray	ray;
	t_f64	xx;
	t_f64	yy;

	xx = (2 * ((x + 0.5) * (1.0 / WIDTH)) - 1) * env->camera.angle * ARATIO;
	yy = (1 - 2 * ((y + 0.5) * (1.0 / HEIGHT))) * env->camera.angle;
	dir = new_vec3f(xx, yy, 0);
	dir = add_vec3f(&dir, &env->camera.up);
	ray = new_ray(env->camera.pos, normal_vec3f(&dir));
	*pixel = trace_ray(&ray, env->objects, 0);
}
Example #4
0
void TCOD_map_compute_fov_diamond_raycasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) {
	map_t *m = (map_t *)map;
	TCOD_list_t perim=TCOD_list_allocate(m->nbcells);
	cell_t *c;
	ray_data_t **r;
	int nbcells;
	int r2=max_radius*max_radius;

	perimidx=0;
	raymap=(ray_data_t **)calloc(sizeof(ray_data_t*),m->nbcells);
	raymap2=(ray_data_t *)calloc(sizeof(ray_data_t),m->nbcells);
	origx=player_x;
	origy=player_y;
	expandPerimeterFrom(m,perim,new_ray(m,0,0));
	while ( perimidx < TCOD_list_size(perim) ) {
		ray_data_t *ray=(ray_data_t *)TCOD_list_get(perim,perimidx);
		int distance = 0;
		if ( r2 > 0 ) distance = ((ray->xloc * ray->xloc) + (ray->yloc * ray->yloc));
		perimidx++;
		if ( distance <= r2) {
			merge_input(m, ray);
			if ( !ray->ignore ) expandPerimeterFrom(m,perim,ray);
		} else ray->ignore=true;
	}

	// set fov data
	c=m->cells;
	r=raymap;
	nbcells=m->nbcells;
	while ( nbcells!= 0 ) {
		if ( *r == NULL || (*r)->ignore
			|| ((*r)->xerr > 0 && (*r)->xerr <= (*r)->xob )
			|| ((*r)->yerr > 0 && (*r)->yerr <= (*r)->yob )
		) {
			c->fov=0;
		} else {
			c->fov=1;
		}
		c++;
		r++;
		nbcells--;
	}
	m->cells[origx+origy*m->width].fov=1;

	// light walls
	if ( light_walls ) {
		int xmin=0, ymin=0, xmax=m->width, ymax=m->height;
		if ( max_radius > 0 ) {
			xmin=MAX(0,player_x-max_radius);
			ymin=MAX(0,player_y-max_radius);
			xmax=MIN(m->width,player_x+max_radius+1);
			ymax=MIN(m->height,player_y+max_radius+1);
		}
		TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1);
		TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1);
		TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1);
		TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1);
	}

	free(raymap);
	free(raymap2);
	TCOD_list_delete(perim);
}
Example #5
0
	Color Renderer::rayTraceRecursive(Shape* scene, Ray& ray, Lights& lights, int maxReflect) {
		IntersectResult result;
		scene->Intersect(ray, &result);
		if (result.geometry) {
			Material* pMaterial = result.geometry->material;
			float reflectiveness = pMaterial->reflectiveness;
			Color color(0, 0, 0);
			std::mt19937 eng(4029349);
			std::uniform_real_distribution<float> fraction_dist;
			for (int i = 0; i < lights.size(); i++) {
				Light* pLight = lights[i];
				Color c;
				if (!pLight->shadow) {
					//no shadow
					Vector3dF incidenceNormal = pLight->incidenceNormal(result.position);
					c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal);
				} else if (pLight->softshadow) {
					Vector3dF incidenceCenter = pLight->incidence(result.position);
					Vector3dF incidenceNormal = incidenceCenter.Normalize();
					Vector3dF rayNormal(-incidenceCenter.y, incidenceCenter.x, 0);
					rayNormal = rayNormal.Normalize();
					float disToLight = 0;
					if (pLight->lightType == LightType_Point) {
						disToLight = (dynamic_cast<PointLight*>(pLight)->pos - result.position).Length();
					}
					int hitTimes = 0;
					int raysPerFan = pLight->shadowrays / 4;
					for (int quadrant = 0; quadrant < 4; quadrant++) {
						for (int r = 0; r < raysPerFan; r++) {
							float angle = quadrant * 90.0f + fraction_dist(eng) * 90.f;
							float dis = fraction_dist(eng) * pLight->radius;
							//printf("<%.1f, %.1f> ", angle, dis);
							Vector3dF d = rayNormal.rotate(incidenceNormal, PI * angle / 180.f);
							Ray shadowrays(result.position, (-incidenceCenter) + d * dis);
							shadowrays.d = shadowrays.d.Normalize();
							IntersectResult _result;
							scene->Intersect(shadowrays, &_result);
							if (_result.geometry) {
								if (disToLight && _result.distance >= disToLight) {
									continue;
								}
								hitTimes++;
							}
						}
						//printf("\n");
					}
					//printf("\n");
					c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal);
					if (hitTimes > 0) {
						//printf("%d\n", hitTimes);
						float black_ratio = hitTimes / (float)pLight->shadowrays;
						//c = c * ( 1.0f - black_ratio) + Color::Black * black_ratio;
						c = c.Modulate(Color::White * (1.0f - black_ratio));
						c = c.clamp();
					}
				}
				else {
					//normal shadow
					Vector3dF incidenceNormal = pLight->incidenceNormal(result.position);
					//Is this light visible 
					Ray shadowrays(result.position, -incidenceNormal);
					IntersectResult _result;
					scene->Intersect(shadowrays, &_result);
					bool canSample = true;
					if (_result.geometry) {
						if (pLight->lightType == LightType_Point) {
							float disToLight = (dynamic_cast<PointLight*>(pLight)->pos - result.position).Length();
							if (disToLight >= _result.distance) {
								canSample = false;
								c = Color::Black;
							}
						}
						else if (pLight->lightType == LightType_Direction) {
							canSample = false;
							c = Color::Black;
						}
					}
					if(canSample){
						c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal);
					}
				}
				color = color + c;
			}
			color = Color(color * (1.0f - reflectiveness));

			if (reflectiveness > 0 && maxReflect > 0) {
				Vector3dF r = Vector3dF(result.normal * (-2 * (result.normal.Dot(ray.d))) + ray.d);
				Ray new_ray(result.position, r);
				Color reflectedColor = rayTraceRecursive(scene, new_ray, lights, maxReflect - 1);
				assert(reflectedColor.r() >= 0 && reflectedColor.g() >= 0 && reflectedColor.b() >= 0);
				color = color + reflectedColor * reflectiveness;
			}
			return color;
		}
		else
			return Color::Black;
	}