home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vectoper.zip
/
RTAlgOps.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-19
|
36KB
|
1,239 lines
#include <stdio.h>
#include <math.h>
#include "RTTypes.h"
#include "RTMatMac.h"
#include "RTVecOps.h"
#include "RTScreen.h"
#include "RTObjOps.h"
#include "RTIMOps.h"
#include "RayTrace.h"
#include "RTIntOps.h"
#include "calypso.H"
extern int RT_sd; // Socket descriptor for display client connection requests
/*
*******************************************************************************
*
* Name: RT_Trace
*
* Purpose: this routine is responsible for determining the closest int-
* ersection (if any) between the ray currently being traced and
* any objects. If an intersection is found, that point is passed
* to "RT_Shade" for shading. RT_Trace returns the color deter-
* mined by RT_Shade if an intersection was found, or a background
* color if not.
*
*
*
* Input Parameters
*
* i_ray - ray currently being traced
* n_i - index of refraction of medium that ray is passing through
* depth - level of recursion
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
Vector
RT_Trace( Ray i_ray, float n_i, int depth)
{
Vector I_pt;
Vector Pt_int;
Vector Pt_norm;
Vector patch_norm;
Boolean int_flg;
int obj_no;
/*
* determine nearest intersection
*/
int_flg = nearest_int(i_ray, &obj_no, &Pt_int, &Pt_norm, &patch_norm);
/*
* if there is an intersection -- shade surface
*/
if (int_flg) {
I_pt = RT_Shade(Pt_int, Pt_norm, patch_norm, i_ray,
&shared->obj_list[obj_no], &shared->obj_props[obj_no],
depth, n_i);
}
/*
* if no intersection & we're at top level -- set a nice background color
*/
else if (depth == 1)
vset(&I_pt, (float) 0.0, (float) 0.0, (float) 0.0);
/*
* if no intersection & we're NOT at top level -- set black background
*/
else
vset(&I_pt, (float) 0.0, (float) 0.0, (float) 0.0);
return (I_pt);
}
/*
*******************************************************************************
*
* Name: RT_Shade
*
* Purpose: this routine applies Whitted's illumination equation
* [eq. 16.55, p. 778 in Computer Graphics (Principles and
* Practice)] to a specified point. In order to accomplish
* this, it applies the Warn Lighting Model at the point.
* It then spawns reflected & refracted rays from the point
* if needed (Ks > 0.2 or Kt > 0.2). The intensities from
* these two rays are then factored into the intensity at
* the point.
*
*
*
* Input Parameters
*
* RT_pt - point to be shaded
* Pt_norm - normal at point to be shaded
* patch_norm - normal of patch containg point to be shaded
* RT_Iray - incident ray at point to be shaded
* obj_ptr - ptr to object containing point to be shaded
* prop_ptr - ptr to structure containing objects optical properties
* depth - level of recursion
* n_i - index pf refraction for medium containg incident ray
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
Vector
RT_Shade( Vector RT_pt, Vector Pt_norm, Vector patch_norm, Ray RT_Iray,
Obj *obj_ptr, Obj_Props *prop_ptr, int depth, float n_i)
{
Vector I;
Vector Ir, It;
Vector U, V;
Vector View_vec;
Vector I_vec;
Vector illum_norm;
Vector Od;
Ray r_ray, t_ray;
float N_dot_I;
float cos_fee;
float n_t;
/*
* initialization
*/
vset (&I, (float) 0.0, (float) 0.0, (float) 0.0);
vset (&Ir, (float) 0.0, (float) 0.0, (float) 0.0);
vset (&It, (float) 0.0, (float) 0.0, (float) 0.0);
/*
*******************************************************************************
*
* illuminate specified point
*
*******************************************************************************
*
* initialize input for illumination model
*/
vset (&View_vec, -(RT_Iray.dir.x), -(RT_Iray.dir.y), -(RT_Iray.dir.z) );
View_vec = VectorScaler_Division( &View_vec, vector_len(&View_vec) );
I_vec = VectorScaler_Division( &RT_Iray.dir, vector_len(&RT_Iray.dir) );
vset (&illum_norm, Pt_norm.x, Pt_norm.y, Pt_norm.z);
Vector saveN = illum_norm;
Od = prop_ptr->Od_out;
/*
* handle case where inside of patch is showing
*/
cos_fee = Dot_Product(&View_vec, &patch_norm);
if (cos_fee <= 0.0) {
vset (&illum_norm, -(illum_norm.x), -(illum_norm.y), -(illum_norm.z));
Od = prop_ptr->Od_in;
}
/*
* if the object is to be texture mapped get texture map color for point
*/
if (prop_ptr->txt_flg)
RT_TextureMap(RT_pt, obj_ptr, &Od);
/*
* apply illumination model - sum diffuse & specular components
*/
Illumination_Model(RT_pt, &illum_norm, &View_vec,
&Od, &prop_ptr->Os,
prop_ptr->Ka, prop_ptr->Kd, prop_ptr->Ks,
&U, &V);
I = Vector_Sum (&I, &U);
I = Vector_Sum (&I, &V);
/*
*******************************************************************************
*
* spawn reflection and transmission rays if needed
*
*******************************************************************************
*/
if (depth < shared->depth_limit) {
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ spawn reflection ray if object is reflective
+ (r_ray.dir = 2.0*N * (NdotL) - View_vector)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
if (prop_ptr->Ks > 0.2) {
/*
* setup reflected ray
*/
N_dot_I = Dot_Product(&illum_norm, &I_vec);
r_ray.origin = RT_pt;
r_ray.dir = VectorScaler_Product(&illum_norm, ((float)2.0)*N_dot_I);
r_ray.dir = Vector_Difference(&I_vec, &r_ray.dir);
r_ray.dir = VectorScaler_Division(&r_ray.dir, vector_len(&r_ray.dir));
/*
* determine intensity contribution from reflected ray
*/
Ir = RT_Trace (r_ray, (float)-1.0, depth+1);
Ir = VectorScaler_Product(&Ir, prop_ptr->Ks);
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ spawn refracted ray if object is transparent
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
if (prop_ptr->Kt > 0.2) {
/*
* determine indices of refraction at interface
*/
if (n_i < 0) {
n_i = (float)1.0;
n_t = prop_ptr->n;
}
else
n_t = (float)1.0;
/*
* setup refracted ray
*/
t_ray.origin = RT_pt;
t_ray.dir = RT_RefractionDirection(View_vec,illum_norm,n_i,n_t);
/*
* determine intensity contribution from refracted ray
*/
It = RT_Trace (t_ray, n_t, depth+1);
It = VectorScaler_Product(&It, prop_ptr->Kt);
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
/*
* add reflected & refracted contributions to intensity for point
*/
I = Vector_Sum(&I, &Ir);
I = Vector_Sum(&I, &It);
} /* end - if (depth < MAX_DEPTH) */
/*
*******************************************************************************
*******************************************************************************
*/
return(I);
}
/*
*******************************************************************************
*
* Name: RT_SetViewParams
*
* Purpose: this routine determines the three parameters that define the
* ray tracing view plane:
*
* - the vector pointing along the AF axis to the origin
* of the view plane (d_AF)
*
* - the vector representing the horizontal axis of the
* view plane (X_bar)
*
* - the vector representing the vertical axis of the view
* plane (Y_bar)
*
* These values are stored in global variables because of their
* importance in ray tracing (especially during debugging).
*
*
*
* Input Parameters
*
* none
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
void
RT_SetViewParams()
{
Vector AF;
float Vrad;
float d;
/*
* determine number of scan lines & pixels / scan line
* (if running batch mode -- put this info in the output file)
*/
npix = shared->vp.scr_reg.max_pt.x - shared->vp.scr_reg.min_pt.x + 1;
nscan = shared->vp.scr_reg.max_pt.y - shared->vp.scr_reg.min_pt.y + 1;
shared->npix = npix;
shared->nscan = nscan;
if (WritePixelsFlag) {
fwrite (&nscan, sizeof(int), 1, ofp);
fwrite (&npix, sizeof(int), 1, ofp);
}
/*
* determine vector to origin of view plane (d_AF)
*/
AF = Vector_Difference(&shared->vp.A, &shared->vp.F);
Vrad = (shared->vp.v/180) * M_PI;
d = ((float)1.0) / tan(Vrad/2);
shared->d_AF = VectorScaler_Division( &AF, vector_len(&AF) );
shared->d_AF = VectorScaler_Product( &shared->d_AF, d);
/*
* determine orthogonal axis vectors of view plane (X_bar & Y_bar)
*/
Cross_Product (&AF, &shared->vp.U, &shared->X_bar);
shared->X_bar = VectorScaler_Division(&shared->X_bar,
vector_len(&shared->X_bar));
Cross_Product (&AF, &shared->X_bar, &shared->Y_bar);
shared->Y_bar = VectorScaler_Division(&shared->Y_bar,
vector_len(&shared->Y_bar));
}
/*
*******************************************************************************
*
* Name: RT_RefractionDirection
*
* Purpose: this routine calculates the direction of the refracted ray
* for a incident ray that reaches the interface between two
* media with different refractive indices. The calculation
* is based on eq. 16.31 (p757) in:
* Computer Graphics (Principles and Practice)
*
*
*
* Input Parameters
*
* I - incident ray direction
* N - normal at medium interface
* n_i -index of refraction for medium containing incident ray
* n_t -index of refraction for medium containing transmitted ray
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
Vector
RT_RefractionDirection(Vector I, Vector N, float n_i, float n_t)
{
Vector T_vec;
Vector nr_I;
float n_r, nr_sq;
float cos_theta_i;
float cos_theta_i_sq;
float cos_theta_t;
n_r = n_i / n_t;
nr_sq = n_r * n_r;
cos_theta_i = Dot_Product(&N, &I);
cos_theta_i_sq = cos_theta_i * cos_theta_i;
cos_theta_t = sqrt(1 - nr_sq * (1 - cos_theta_i_sq) );
nr_I = VectorScaler_Product(&I, n_r);
T_vec = VectorScaler_Product(&N, n_r*cos_theta_i - cos_theta_t);
T_vec = Vector_Difference(&T_vec, &nr_I);
return(T_vec);
}
/*
*******************************************************************************
*
* Name: RT_DirectionVector
*
* Purpose: this routine determines the direction vectors for rays cast
* through the ray tracing view plane from the center of pro-
* jection. This is done by translating from pixel edge co-
* ordinate space to the u-v space of the view plane and
* adding together the following three components:
*
* - distance along AF axis to view plane origin (d_AF)
*
* - distance from view plane origin to pixel edge in X_bar
* direction (u)
*
* - distance from view plane origin to pixel edge in Y_bar
* direction (v)
*
*
*
* Input Parameters
*
* pix - number of pixel
* scan - number of scan line containing pixel
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
Vector
RT_DirectionVector(float pix, float scan)
{
PT_uv Puv;
Vector dir, vec;
float x_diff, y_diff;
/*
* determine pixel edge in pixel edge coordinates
*/
x_diff = (float)(shared->vp.scr_reg.max_pt.x - shared->vp.scr_reg.min_pt.x + 1);
y_diff = (float)(shared->vp.scr_reg.max_pt.y - shared->vp.scr_reg.min_pt.y + 1);
/*
* translate coordinates to uv space of view plane
*/
Puv.u = (pix - (x_diff / 2)) / (x_diff / 2);
Puv.v = (scan - (y_diff / 2)) / (y_diff / 2);
/*
* determine direction vector for ray through point on view plane
*/
dir = shared->d_AF;
vec = VectorScaler_Product( &shared->X_bar, Puv.u);
dir = Vector_Sum(&dir, &vec);
vec = VectorScaler_Product( &shared->Y_bar, Puv.v);
dir = Vector_Sum(&dir, &vec);
return(dir);
}
/*
*******************************************************************************
*
* Name: RT_SetPixels
*
* Purpose: this routine converts pixel intensity values (for a given
* scan line) to RGB values and writes out these values accord-
* based on flagged cases:
*
* - interactive case: (debug_flag & batch_flag = FALSE)
* ray tracing is being run interactively and the output
* is displayed directly on the screen in RGB mode.
*
* - debug case: (debug_flag = TRUE)
* ray tracing is being run interactively in debug mode
* and the output is displayed on the display screen as
* integer RGB values.
*
* - batch case: (batch_flag = TRUE)
* ray tracing is being run in batch mode and the output
* is written to a data file for later display
*
*
*
* Input Parameters
*
* Ipix - array of pixel intensity values to be displayed
* scan - scan line number for array of pixel intensity values
* npix - number of pixel intensity values in pixel array (Ipix)
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
void
RT_SetPixels (Vector Ipix[], int scan, int npix)
{
short XmitBuffer[5000];
short red_i, green_i, blue_i;
short i, n;
int XB_next = 0;
n = (short) npix;
if (debug_flag)
printf ("\n\n scan: %d -- of nscan\n", scan);
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ write out pixel values
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
for (i=0; i<n; i++) {
/*
* calculate pixel values from intensity values
*/
red_i = (short) MIN( (( 255.0 * (Ipix[i].x) ) + 0.5), 255.0 );
green_i = (short) MIN( (( 255.0 * (Ipix[i].y) ) + 0.5), 255.0 );
blue_i = (short) MIN( (( 255.0 * (Ipix[i].z) ) + 0.5), 255.0 );
/*
* handle case where pixel values are written to a file as RGB values
*/
if (! debug_flag) {
if (WritePixelsFlag) {
fwrite ( (char *) &red_i, sizeof(short), 1, ofp);
fwrite ( (char *) &green_i, sizeof(short), 1, ofp);
fwrite ( (char *) &blue_i, sizeof(short), 1, ofp);
}
if (XmitPixelsFlag) {
XmitBuffer[XB_next++] = red_i;
XmitBuffer[XB_next++] = green_i;
XmitBuffer[XB_next++] = blue_i;
}
}
/*
* handle case where pixel values are written to screen as RGB values
*/
else
printf ("I: (%f,%f, %f) RGB: (%d, %d, %d)\n",
Ipix[i].x, Ipix[i].y, Ipix[i].z,
red_i, green_i, blue_i);
} /* end -- for loop */
if (XmitPixelsFlag) {
RT_XmitPixels(XmitBuffer, scan, npix);
if (scan == shared->ScanLimit-1)
RT_XmitPixels(NULL, -1, -1);
}
}
/*
*******************************************************************************
*
* Name: RT_XmitPixels
*
* Purpose: this routine is responsible for transmitting a specified (buffer)
* scan line to any interested clients.
* TECHNICAL NOTE:
* Because of limitations of the SetPixel routine in Windows NT
* clients will not attempt to display their data until they are told
* that a parallel step has been completed. This routine will send a
* sentinel value indicating this fact to all clients if it determines
* that the pointer to buffer is NULL.
*
*
* Input Parameters
*
* buffer - array of pixel intensity values to be transmitted
* scan_no - scan line number for array of pixel intensity values
* npix - number of pixel intensity values in pixel array (buffer)
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
void
RT_XmitPixels (short buffer[], int scan_no, int npix)
{
static int RT_DC[100];
static int num_clients = 0;
struct timeval TimeOut;
fd_set mask;
int scanpix[2];
int nclients;
int i;
/*
+++++++++++++++++++++++++++++++++++++++++++++++++
+ setup pending connections and send new
+ client and inform it of image size
+++++++++++++++++++++++++++++++++++++++++++++++++
*/
FD_ZERO(&mask);
FD_SET(RT_sd, &mask);
TimeOut.tv_sec = 0;
TimeOut.tv_usec = 0;
scanpix[0] = shared->nscan;
scanpix[1] = shared->npix;
if ((nclients = select(FD_SETSIZE, &mask, NULL, NULL, &TimeOut)) == SOCKET_ERROR) {
perror("Select Error: ");
exit(0);
}
for (i=0; i<nclients; i++) {
RT_DC[num_clients] = accept(RT_sd, 0, 0);
if (RT_Send(RT_DC[num_clients++], (char *) scanpix, 2*sizeof(int)) != 8) {
printf ("Error: Scan Prefix wrong length. -- EXITING\n");
exit(1);
}
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++
+ send pixels to all connected clients
+++++++++++++++++++++++++++++++++++++++++++++++++
*/
if (num_clients == 0) {
printf("Warning: For Scanline %d No Clients Listening -- Data Tranmission NOT Performed\n", scan_no);
return;
}
for (i=0; i<num_clients; i++) {
//
// if there is data buffer -- send scan no. and data to client
//
if (buffer != NULL) {
if (RT_Send(RT_DC[i], (char *) &scan_no, sizeof(int)) != 4) {
printf ("Error: Scan Prefix wrong length. -- EXITING\n");
exit(1);
}
if (RT_Send(RT_DC[i], (char *) buffer, 3*npix*sizeof(short)) != 3*npix*sizeof(short)) {
printf ("Error: Scan Data wrong length. -- EXITING\n");
exit(1);
}
} /* end -- if buffer is NULL */
//
// if there is no data buffer -- send sentinal to client
//
else {
if (RT_Send(RT_DC[i], (char *) &scan_no, sizeof(int)) != 4) {
printf ("Error: Scan Prefix wrong length. -- EXITING\n");
exit(1);
}
} /* end -- else buffer is NOT NULL */
} /* end -- for num_clients */
}
/*
*******************************************************************************
*
* Name: RT_Send
*
* Purpose: this routine contains the low level system calls needed to send
* data to a client.
*
*
*
* Input Parameters
*
* sd - socket descriptor
* buf - buffer containing data to be send
* bytes - number of data bytes in buffer
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
int
RT_Send (int sd, char buf[], int bytes)
{
int size, SendSize;
char *cPtr;
cPtr = buf;
size = bytes;
while (size > 0) {
if ((SendSize = send(sd, cPtr, size, 0)) == -1) {
perror("Xmit Error: ");
exit(1);
}
else if (SendSize == 0)
return(0);
cPtr += SendSize;
size -= SendSize;
}
return(bytes);
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
File: texture_map.c
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
/*
*******************************************************************************
*
* Name: RT_TextureMap
*
* Purpose: this routine was designed to be a general texture mapping
* routine for spheres, triangles, & rectangles. However, it
* is currently hardwired to map a checkerboard onto a plane.
*
*
*
* Input Parameters
*
* pt - point to mapped into texture map
* obj_ptr - pointer to object containing pt
*
*
* Output Parameters
*
* Od - texture map color for point
*
*
*******************************************************************************
*/
void
RT_TextureMap(Vector pt, Obj *obj_ptr, Vector *Od)
{
Rect_Obj *r_ptr;
Point Pt;
float Xmax, Xmin;
float Ymax, Ymin;
float Umin = (float)0.0, Umax = (float)1.0;
float Vmin = (float)0.0, Vmax = (float)1.0;
float u, v;
int u_val, v_val;
int M = 12;
switch (obj_ptr->label) {
case SPHERE:
break;
case TRIANGLE:
break;
case RECTANGLE:
r_ptr = (Rect_Obj *) obj_ptr->ptr;
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ map rectangle to 2D space
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
switch(r_ptr->normal) {
/*
* handle case where rectangle || to y-z plane
*/
case X_AXIS:
Pt.x = pt.y;
Pt.y = pt.z;
Xmax = r_ptr->max_pt.y;
Xmin = r_ptr->min_pt.y;
Ymax = r_ptr->max_pt.z;
Ymin = r_ptr->min_pt.z;
break;
/*
* handle case where rectangle || to x-z plane
*/
case Y_AXIS:
Pt.x = pt.x;
Pt.y = pt.z;
Xmax = r_ptr->max_pt.x;
Xmin = r_ptr->min_pt.x;
Ymax = r_ptr->max_pt.z;
Ymin = r_ptr->min_pt.z;
break;
/*
* handle case where rectangle || to x-y plane
*/
case Z_AXIS:
Pt.x = pt.x;
Pt.y = pt.y;
Xmax = r_ptr->max_pt.x;
Xmin = r_ptr->min_pt.x;
Ymax = r_ptr->max_pt.y;
Ymin = r_ptr->min_pt.y;
break;
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ determine texture at point
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*
* map rectangle to uv space
*/
u = ( (Pt.x - Xmin) * (Umax-Umin) / (Xmax-Xmin) ) + Umin;
v = ( (Pt.y - Ymin) * (Vmax-Vmin) / (Ymax-Ymin) ) + Vmin;
/*
* determine Od for checkerboard texture
*/
u_val = (int) (u * (float) M) % 2;
v_val = (int) (v * (float) M) % 2;
if (u_val == v_val)
vset(Od, (float) 1.0, (float) 1.0, (float) 0.0);
else
vset(Od, (float) 1.0, (float) 0.0, (float) 0.0);
break;
}
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
File: configure.c
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
extern FILE *ofp;
/*
*******************************************************************************
*
* Name: RT_Configure
*
* Purpose: this routine sets the scene configuration from an input file
* specified by the input parameter "config_file"
*
*
*
* Input Parameters
*
* config_file - input data file that specified scene parameters
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
void
RT_Configure(char *config_file)
{
Obj_Props *p_ptr;
Light *l_ptr;
Vector Od_in, Od_out, Os;
float Ka, Kd, Ks, Kt;
float refract_index;
int txt_flg;
FILE *cntl_fp;
FILE *obj_fp;
Boolean init_objects = TRUE;
Boolean viewport_flag = FALSE;
Boolean objects_flag = FALSE;
char cntl_str[20];
char file_str[50];
char lite_str[50];
int obj_cnt = 0, lite_cnt = 0;
int num_obj;
int x_res, y_res;
int i;
int junk;
if ((cntl_fp = fopen(config_file, "r")) == NULL) {
printf ("***** Error: Batch Configuration File Open Failed");
printf (" -- EXITING *****\n");
perror("File Error Was: ");
printf("Configuration File Name Was: %s\n", config_file);
exit(1);
}
fscanf (cntl_fp, "%s\n", cntl_str);
/*
*******************************************************************************
*
* interpret configuration commands
*
*******************************************************************************
*/
while (strcmp("#end", cntl_str) != 0) {
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* handle command to open batch output data file
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
if (strcmp("#output", cntl_str) == 0) {
fscanf (cntl_fp, "%s", file_str);
if ((ofp = fopen(file_str, "wb")) == NULL) {
printf ("***** Error: Output File Open Failed");
printf (" -- EXITING *****\n");
perror("File Error Was: ");
exit(1);
}
WritePixelsFlag = TRUE;
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* handle command to read object data file
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
else if (strcmp("#obj", cntl_str) == 0) {
if (viewport_flag) {
printf ("***** Error: Viewport Has been Specified *****\n");
printf (" All objects must be specified before a");
printf (" Viewport control card is seen -- EXITING\n");
exit (1);
}
fscanf (cntl_fp, "%s", file_str);
if ((obj_fp = fopen(file_str, "r")) == NULL) {
printf ("***** Error: Input Object Data File Open Failed");
printf (" -- EXITING *****\n");
perror("File Error Was: ");
exit(1);
}
fscanf (cntl_fp, "%f %f %f\n", &Od_in.x, &Od_in.y, &Od_in.z);
fscanf (cntl_fp, "%f %f %f\n", &Od_out.x, &Od_out.y, &Od_out.z);
fscanf (cntl_fp, "%f %f %f\n", &Os.x, &Os.y, &Os.z);
fscanf (cntl_fp, "%f %f %f %f %d\n", &Ka, &Kd, &Ks, &Kt,
&txt_flg);
fscanf (cntl_fp, "%f\n", &refract_index);
fscanf (obj_fp, "%d\n", &num_obj);
for (i=0; i<num_obj; i++) {
build_object(obj_fp, init_objects);
init_objects = FALSE;
p_ptr = &shared->obj_props[obj_cnt];
p_ptr->Od_in = Od_in;
p_ptr->Od_out = Od_out;
p_ptr->Os = Os;
p_ptr->Ka = Ka;
p_ptr->Kd = Kd;
p_ptr->Ks = Ks;
p_ptr->Kt = Kt;
p_ptr->txt_flg = txt_flg;
p_ptr->n = refract_index;
obj_cnt++;
} /* end for loop */
objects_flag = TRUE;
fclose(obj_fp);
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* handle command to set phong constant
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
else if (strcmp("#phong_constant", cntl_str) == 0) {
fscanf (cntl_fp, "%f\n", &shared->PhongConst);
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* handle command to set manimum recurrsive depth
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
else if (strcmp("#depth_limit", cntl_str) == 0) {
fscanf (cntl_fp, "%d\n", &shared->depth_limit);
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* handle command to set manimum recurrsive depth
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
else if (strcmp("#scan_set_count", cntl_str) == 0) {
fscanf (cntl_fp, "%d\n", &nIter);
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* handle command to set number of thread segments
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
else if (strcmp("#thread_segments", cntl_str) == 0) {
if ( num_T <= 0) {
if (! viewport_flag) {
printf ("***** Error: Viewport has NOT been Specified ");
printf ("*****\n");
printf (" The thread count cannot be specified before a");
printf (" Viewport control card is seen -- EXITING\n");
exit (1);
}
fscanf (cntl_fp, "%d\n", &num_T);
if (num_T <= 0) {
printf (" ***** Error: Thread Count MUST be greater than ");
printf ("0 -- EXITING *****\n");
exit(0);
}
}
else
fscanf (cntl_fp, "%d\n", &junk);
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* handle command to set viewport size
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
else if (strcmp("#viewport", cntl_str) == 0) {
if (! objects_flag) {
printf ("***** Error -- No Objects Specified *****\n");
printf (" All objects must be specified before a");
printf (" Viewport control card is seen -- EXITING\n");
exit (1);
}
fscanf (cntl_fp, "%d %d\n", &x_res, &y_res);
shared->vp.scr_reg.min_pt.x = work_reg.min_pt.x;
shared->vp.scr_reg.max_pt.x = shared->vp.scr_reg.min_pt.x+x_res-1;
shared->vp.scr_reg.max_pt.y = work_reg.max_pt.y;
shared->vp.scr_reg.min_pt.y = shared->vp.scr_reg.max_pt.y-y_res+1;
fscanf (cntl_fp, "%f %f %f\n", &shared->vp.F.x, &shared->vp.F.y,
&shared->vp.F.z);
fscanf (cntl_fp, "%f %f %f\n", &shared->vp.A.x, &shared->vp.A.y,
&shared->vp.A.z);
fscanf (cntl_fp, "%f %f %f\n", &shared->vp.U.x, &shared->vp.U.y,
&shared->vp.U.z);
fscanf (cntl_fp, "%f\n", &shared->vp.v);
shared->vp.F = (vector_len(&shared->vp.F) != 0.0)?
shared->vp.F : obj_defaults.F;
shared->vp.A = (vector_len(&shared->vp.A) != 0.0)?
shared->vp.A : obj_defaults.A;
shared->vp.U = (vector_len(&shared->vp.U) != 0.0)?
shared->vp.U : obj_defaults.U;
shared->vp.v = (shared->vp.v != 0.0)? shared->vp.v : obj_defaults.v;
viewport_flag = TRUE;
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* handle command to set light source
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
else if (strcmp("#light_source", cntl_str) == 0) {
l_ptr = &shared->lights[lite_cnt];
l_ptr->on = TRUE;
fscanf (cntl_fp, "%f %f %f\n",&l_ptr->L_pt.x, &l_ptr->L_pt.y,
&l_ptr->L_pt.z);
fscanf (cntl_fp, "%f %f %f\n",&l_ptr->I.x, &l_ptr->I.y,
&l_ptr->I.z);
l_ptr->L_pt = (vector_len(&l_ptr->L_pt) != 0.0)?
l_ptr->L_pt : obj_defaults.F;
fscanf (cntl_fp, "%s\n", lite_str);
if (strcmp("directed", lite_str) == 0) {
l_ptr->directed = TRUE;
fscanf (cntl_fp, "%f %f %f\n",&l_ptr->L_a.x, &l_ptr->L_a.y,
&l_ptr->L_a.z);
fscanf (cntl_fp, "%f",&l_ptr->ro);
fscanf (cntl_fp, "%f\n",&l_ptr->cos_delta);
}
else {
l_ptr->directed = FALSE;
vset(&l_ptr->L_a, (float) 0.0, (float) 0.0, (float) 0.0);
l_ptr->ro = (float) 0.0;
l_ptr->cos_delta = (float) 0.0;
}
lite_cnt++;
}
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
fscanf (cntl_fp, "%s\n", cntl_str);
} /* end while */
}