Trace.cpp
上传用户:lhwx1029
上传日期:2013-03-07
资源大小:1173k
文件大小:18k
- /** 3DGPL *************************************************
- * (RGB hardware) *
- * Simple 3D ray tracing engine. *
- * *
- * Defines: *
- * TR_sphere_init Actualy, does nothing; *
- * TR_sphere_intersect Closest of two; *
- * TR_sphere_normal From a point; *
- * TR_polygon_init Compute the plane equation; *
- * TR_polygon_intersect t of the intersection; *
- * TR_polygon_normal Always constant; *
- * TR_init_world Init all objects; *
- * TR_trace_world Building an image. *
- * *
- * Internals: *
- * TRI_make_ray_point Construct from two points; *
- * TRI_make_ray_vector From a point and a vector; *
- * TRI_on_ray Point from ray coef; *
- * TRI_illuminate Local illumination; *
- * TRI_shadow_ray If a lightsource is shadowed;*
- * TRI_direct_ray Computes one pixel's colour. *
- * *
- * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca) *
- **********************************************************/
- #include "Graphics.h" /* G_pixel */
- #include "Colour.h" /* colour related */
- #include "Vector.h" /* linear algebra related */
- #include "Trace.h" /* self definition */
- #include <math.h> /* sqrt */
- #include <stdlib.h> /* malloc */
- int TR_rendering_type; /* rendering options */
- float TR_viewer[V_LNG_VECTOR]; /* position of the viewer */
- float TR_screen[V_LNG_VECTOR]; /* origine of the screen */
- float TR_screen_u[V_LNG_VECTOR]; /* screen orientation vectors */
- float TR_screen_v[V_LNG_VECTOR];
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Constructing a ray from two points. *
- * *
- * RETURNS: Constructed ray. *
- * -------- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- struct TR_ray *TRI_make_ray_point(struct TR_ray *r,float *from,
- float *to
- )
- {
- //设置光线矢量的起始点
- V_set(r->tr_start,from);
- //计算光线的矢量方向
- V_difference(r->tr_codirected,to,from);
- return(r);
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Constructing a ray from a point and a vector. *
- * *
- * RETURNS: Constructed ray. *
- * -------- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- struct TR_ray *TRI_make_ray_vector(struct TR_ray *r,float *from,
- float *vector
- )
- {
- V_set(r->tr_start,from);
- V_set(r->tr_codirected,vector);
- return(r);
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Returns point at distance t from the origine. *
- * *
- * RETURNS: Constructed vertex. *
- * -------- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- float *TRI_on_ray(float *point,struct TR_ray *r,float t)
- {
- point[0]=r->tr_start[0]+r->tr_codirected[0]*t;
- point[1]=r->tr_start[1]+r->tr_codirected[1]*t;
- point[2]=r->tr_start[2]+r->tr_codirected[2]*t;
- return(point);
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Computing illumination of a intersected surface point.*
- * *
- * RETURNS: An RGB triple. *
- * -------- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- float *TRI_illuminate(float *light,struct TR_point_light *l,
- struct TR_matter *material,
- float *normal,
- float *where,
- float *viewer
- )
- {
- int i;
- float lightvector[V_LNG_VECTOR],viewvector[V_LNG_VECTOR],reflect[V_LNG_VECTOR];
- float diffuseratio,specularratio,specularfun;
- V_unit_vector(lightvector,where,l->tr_centre);
- V_unit_vector(viewvector,where,viewer);
- if((diffuseratio=V_scalar_product(normal,lightvector))>0)
- {
- if(TR_rendering_type&(TR_DIFFUSE|TR_SPECULAR))
- {
- light[0]+=l->tr_intensity[0]*material->tr_diffuse[0]*diffuseratio;
- light[1]+=l->tr_intensity[1]*material->tr_diffuse[1]*diffuseratio;
- light[2]+=l->tr_intensity[2]*material->tr_diffuse[2]*diffuseratio;
- }
- /* diffuse term */
- if(TR_rendering_type&TR_SPECULAR)
- {
- reflect[0]=2*diffuseratio*normal[0]-lightvector[0];
- reflect[1]=2*diffuseratio*normal[1]-lightvector[1];
- reflect[2]=2*diffuseratio*normal[2]-lightvector[2];
- if((specularratio=V_scalar_product(reflect,viewvector))>0)
- {
- for(specularfun=1,i=0;i<material->tr_exponent;i++) specularfun*=specularratio;
- light[0]+=l->tr_intensity[0]*material->tr_specular*specularfun;
- light[1]+=l->tr_intensity[1]*material->tr_specular*specularfun;
- light[2]+=l->tr_intensity[2]*material->tr_specular*specularfun;
- } /* specular term */
- }
- }
- return(light);
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Casting a ray towards a lightsource to find out if *
- * it is hidden by other objects or not. *
- * *
- * RETURNS: 1 light source visible; 0 otherwise. *
- * -------- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- int TRI_shadow_ray(struct TR_world *w,
- struct TR_point_light *l,
- float *point,
- int cur_obj
- )
- {
- float t=0.0;
- int i;
- struct TR_ray r;
- TRI_make_ray_point(&r,point,l->tr_centre);
- for(i=0;i<w->tr_no_objects;i++) /* finding intersection */
- {
- if(i!=cur_obj)
- {
- switch(w->tr_objects[i]->tr_type)
- {
- case TR_SPHERE: t=TR_sphere_intersect(&r,(struct TR_sphere*)w->tr_objects[i]);
- break;
- case TR_POLYGON: t=TR_polygon_intersect(&r,(struct TR_polygon*)w->tr_objects[i]);
- break;
- }
- if((t>0)&&(t<=1)) return(1); /* first intersection is enough */
- }
- }
- return(0);
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Casting a ray into the world, recursing to compute *
- * environmental reflections. *
- * *
- * RETURNS: Illumination for the pixel. *
- * -------- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- float *TRI_direct_ray(float *light,struct TR_world *w,
- struct TR_ray *r,
- int cur_obj,
- int depth
- )
- {
- int i,min=0,no_inter=0;
- float objt[TR_MAX_SPHERES],t=0.0;
- int obj[TR_MAX_SPHERES];
- struct TR_ray rr;
- float where[V_LNG_VECTOR]; /* current intersection */
- float normal[V_LNG_VECTOR]; /* of the current intersection */
- float viewer[V_LNG_VECTOR],reflect[V_LNG_VECTOR],rlight[V_LNG_VECTOR];
- if(depth!=0)
- {
- for(i=0;i<w->tr_no_objects;i++) /* finding intersection */
- {
- if(i!=cur_obj) /* with itself, no sense */
- {
- switch(w->tr_objects[i]->tr_type)
- {
- case TR_SPHERE: t=TR_sphere_intersect(r,(struct TR_sphere*)w->tr_objects[i]);
- //同球求交
- break;
- case TR_POLYGON: t=TR_polygon_intersect(r,(struct TR_polygon*)w->tr_objects[i]);
- //同多边形求交
- break;
- }
- if(t>0) /* not behind the ray */
- {
- objt[no_inter]=t; obj[no_inter++]=i; /* a valid intersection */
- }
- }
- }
- if(no_inter!=0) /* if some objects intersected */
- {
- for(i=1;i<no_inter;i++)
- if(objt[min]>objt[i]) min=i; /* finding closest intersection */
- light[0]+=w->tr_objects[obj[min]]->tr_material.tr_ambient[0]*w->tr_ambient[0];
- light[1]+=w->tr_objects[obj[min]]->tr_material.tr_ambient[1]*w->tr_ambient[1];
- light[2]+=w->tr_objects[obj[min]]->tr_material.tr_ambient[2]*w->tr_ambient[2];
- TRI_on_ray(where,r,objt[min]); /* intersection's coordinate */
- switch(w->tr_objects[obj[min]]->tr_type)
- {
- //
- case TR_SPHERE: TR_sphere_normal(normal,where,(struct TR_sphere*)w->tr_objects[obj[min]]);
- break;
- case TR_POLYGON: TR_polygon_normal(normal,where,(struct TR_polygon*)w->tr_objects[obj[min]]);
- break;
- }
- for(i=0;i<w->tr_no_point_lights;i++) /* illumination from each light */
- {
- if((!TRI_shadow_ray(w,w->tr_point_lights[i],where,obj[min]))||
- (!(TR_rendering_type&TR_SHADOW))
- )
- TRI_illuminate(light,w->tr_point_lights[i],
- &w->tr_objects[obj[min]]->tr_material,
- normal,where,TR_viewer
- );
- }
- if(TR_rendering_type&TR_REFLECT)
- {
- V_unit_vector(viewer,where,TR_viewer);
- V_multiply(reflect,normal,V_scalar_product(normal,viewer)*2);
- V_difference(reflect,reflect,viewer);
- TRI_make_ray_vector(&rr,where,reflect); /* prepare recursive ray */
- TRI_direct_ray(V_zero(rlight),w,&rr,obj[min],depth-1);
- light[0]+=rlight[0]*w->tr_objects[obj[min]]->tr_material.tr_reflect;
- light[1]+=rlight[1]*w->tr_objects[obj[min]]->tr_material.tr_reflect;
- light[2]+=rlight[2]*w->tr_objects[obj[min]]->tr_material.tr_reflect;
- }
- }
- }
- return(light);
- }
- /**********************************************************
- * Setting the rendering type. *
- **********************************************************/
- void TR_init_rendering(int type)
- {
- TR_rendering_type=type;
- }
- /**********************************************************
- * Setting the camera parameter, where TR_viewer stores *
- * position of the viewer's eye, TR_screen origine of the *
- * projection plane, TR_screen_u and TR_screen_v *
- * orientation of the projection plane in the world *
- * space. *
- **********************************************************/
- //摄像机参数的设置,
- //TR_viever存储遮视窗eye的位置