v21i018: A ray tracing program, Patch3

Rich Salz rsalz at uunet.uu.net
Thu Feb 8 07:54:07 AEST 1990


Submitted-by: Craig Kolb <craig at weedeater.math.yale.edu>
Posting-number: Volume 21, Issue 18
Archive-name: rayshade/patch3

System: rayshade version 3.0
Patch #: 3
Priority: MEDIUM
Subject: Patch #2, continued.

Fix:	From rn, say "| patch -p -N -d DIR", where DIR is your rayshade source
	directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
	If you don't have the patch program, apply the following by hand,
	or get patch (version 2.0, latest patchlevel).

	After patching:
		make depend
		make

	If patch indicates that patchlevel is the wrong version, you may need
	to apply one or more previous patches, or the patch may already
	have been applied.  See the patchlevel.h file to find out what has or
	has not been applied.  In any event, don't continue with the patch.


Index: src/patchlevel.h
Prereq: 2
1c1
< #define PATCHLEVEL 2
---
> #define PATCHLEVEL 3

Index: src/voxels.c
*** src/voxels.c.old	Thu Dec  7 23:21:58 1989
--- src/voxels.c	Thu Dec  7 23:21:59 1989
***************
*** 18,26 ****
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: voxels.c,v 3.0 89/10/27 02:06:09 craig Exp $
   *
   * $Log:	voxels.c,v $
   * Revision 3.0  89/10/27  02:06:09  craig
   * Baseline for first official release.
   * 
--- 18,29 ----
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: voxels.c,v 3.0.1.1 89/12/06 16:33:29 craig Exp $
   *
   * $Log:	voxels.c,v $
+  * Revision 3.0.1.1  89/12/06  16:33:29  craig
+  * patch2: Added calls to new error/warning routines.
+  * 
   * Revision 3.0  89/10/27  02:06:09  craig
   * Baseline for first official release.
   * 
***************
*** 89,95 ****
  		 * in case...
  		 */
  		make_unbounded(obj, grid);
! 		fprintf(stderr,"Strange, engrid got an unbounded object...\n");
  		return;
  	    }
  
--- 92,98 ----
  		 * in case...
  		 */
  		make_unbounded(obj, grid);
! 		RSwarning("Strange, engrid got an unbounded object...\n");
  		return;
  	    }
  
Index: doc/rayshade.1
*** doc/rayshade.1.old	Thu Dec  7 23:18:57 1989
--- doc/rayshade.1	Thu Dec  7 23:19:01 1989
***************
*** 1,8 ****
  .\" Manual page for rayshade, 'troff -man' format.
  .\"
! .\" $Id: rayshade.1,v 3.0.1.1 89/11/17 16:57:19 craig Exp Locker: craig $
  .\"
  .\" $Log:	rayshade.1,v $
  .\" Revision 3.0.1.1  89/11/17  16:57:19  craig
  .\" patch1: Documented new -w option.
  .\" 
--- 1,38 ----
  .\" Manual page for rayshade, 'troff -man' format.
  .\"
! .\" $Id: rayshade.1,v 3.0.1.11 89/12/06 17:21:39 craig Exp $
  .\"
  .\" $Log:	rayshade.1,v $
+ .\" Revision 3.0.1.11  89/12/06  17:21:39  craig
+ .\" patch2: Added suggestion to use cpp.
+ .\" 
+ .\" Revision 3.0.1.10  89/12/06  16:42:54  craig
+ .\" patch2: Removed documentation of #include handling.
+ .\" 
+ .\" Revision 3.0.1.9  89/12/03  17:59:43  craig
+ .\" patch2: More typos...
+ .\" 
+ .\" Revision 3.0.1.8  89/12/02  19:52:04  craig
+ .\" patch2: General cleanup.
+ .\" 
+ .\" Revision 3.0.1.7  89/12/02  16:48:37  craig
+ .\" patch2: Documented -F option.
+ .\" 
+ .\" Revision 3.0.1.6  89/12/02  15:10:09  craig
+ .\" patch2: Fixed various typos, credited depth of field code.
+ .\" 
+ .\" Revision 3.0.1.5  89/12/02  14:36:44  craig
+ .\" patch2: Documented "aperture" and "focaldist".
+ .\" 
+ .\" Revision 3.0.1.4  89/11/27  18:44:19  craig
+ .\" patch2: Expanded and corrected the documentation of colormaps.
+ .\" 
+ .\" Revision 3.0.1.3  89/11/27  18:06:32  craig
+ .\" patch2: Documented mist, corrected fog documentation & various typos.
+ .\" 
+ .\" Revision 3.0.1.2  89/11/27  15:20:49  craig
+ .\" patch2: Corrected heightfield documentation.
+ .\" 
  .\" Revision 3.0.1.1  89/11/17  16:57:19  craig
  .\" patch1: Documented new -w option.
  .\" 
***************
*** 14,20 ****
  .TH RAYSHADE  1G "September 11, 1989"
  .UC 4
  .SH NAME
! rayshade \- a raytracing program
  .SH SYNOPSIS
  .B rayshade
  [
--- 44,50 ----
  .TH RAYSHADE  1G "September 11, 1989"
  .UC 4
  .SH NAME
! rayshade \- a ray tracing program
  .SH SYNOPSIS
  .B rayshade
  [
***************
*** 25,31 ****
  .SH DESCRIPTION
  .I Rayshade
  reads a file describing a scene to be rendered and produces a
! Utah Raster RLE format file of the raytraced image.
  .br
  .SH OPTIONS
  .TP
--- 55,61 ----
  .SH DESCRIPTION
  .I Rayshade
  reads a file describing a scene to be rendered and produces a
! Utah Raster RLE format file of the ray-traced image.
  .br
  .SH OPTIONS
  .TP
***************
*** 38,43 ****
--- 68,76 ----
  .B \-E \fIeye_separation\fR
  Set eye separation for stereo imaging.
  .TP
+ .B \-F \fIreport_freq\fR
+ Set frequency, in lines, of status report (default 10).
+ .TP
  .B \-h
  Print a short usage message.
  .TP
***************
*** 87,110 ****
  .B \-v
  Write verbose output to standard output.
  .TP
- .B \-w
- Write verbose worker information to the standard error.
- .TP
  .B \-W \fIworkers\fR
! Specify number of worker processes (Linda implementation only).
  .br
  .SH OVERVIEW
  .PP
  .I Rayshade
! is an raytracer capable of raytracing images of objects composed
  of a large number of primitive objects.
! .I Rayhade
  reads a series of lines supplied on the standard input or contained
  in the file named on the command line.
  After reading the input file,
  .I rayshade
! raytraces the image from
! the bottom upwards.  As each scanline is traced, pixels are written to
  a Utah Raster RLE format image file.  By default, this image file is written
  to the standard output, and
  information messages and statistics
--- 120,142 ----
  .B \-v
  Write verbose output to standard output.
  .TP
  .B \-W \fIworkers\fR
! Specify number of worker processes (Linda version only).
! .TP
! .B \-w
! Write verbose worker information to the standard error (Linda version only).
  .br
  .SH OVERVIEW
  .PP
  .I Rayshade
! is an ray tracer capable of rendering images composed
  of a large number of primitive objects.
! .I Rayshade
  reads a series of lines supplied on the standard input or contained
  in the file named on the command line.
  After reading the input file,
  .I rayshade
! renders the image.  As each scanline is rendered, pixels are written to
  a Utah Raster RLE format image file.  By default, this image file is written
  to the standard output, and
  information messages and statistics
***************
*** 125,138 ****
  and range from 0
  (zero intensity) to 1. (full intensity).
  .PP
- A
- .B #include
- directive is supported which, as in the C language,
- causes the contents of the quoted filename which follows to be read and
- effectively inserted at that point in the input file.  Be warned that
- .I rayshade
- does no checking for mutual or recursive inclusion of files.
- .PP
  The following sections describe the keywords which may be included
  in the input file.  Items in boldface type are literals, while 
  square brackets surround optional items.
--- 157,162 ----
***************
*** 173,179 ****
  "-R 128 128" on the command line.
  .TP
  \fBscreen \fIx_resolution y_resolution\fR
! Specifies the horizontal and vertical resolution of the image to be traced.
  This command may be overridden through use of
  the \fB-R\fR option.
  The default resolution
--- 197,203 ----
  "-R 128 128" on the command line.
  .TP
  \fBscreen \fIx_resolution y_resolution\fR
! Specifies the horizontal and vertical resolution of the image to be rendered.
  This command may be overridden through use of
  the \fB-R\fR option.
  The default resolution
***************
*** 190,195 ****
--- 214,245 ----
  By default, the image is written to the standard output.
  This command may be overridden through the use of the \fB-O\fR option.
  .TP
+ \fBaperture \fIaperture_radius\fR
+ The \fIaperture_radius\fR is the radius, in world units, of the aperture
+ centered at the eye point.
+ This controls,
+ in conjunction with \fBfocaldist\fR, the depth of field,
+ and thus the amount of focus blur present in the final image.
+ Rays are cast from various places on the
+ aperture disk towards a point which is
+ \fIfocal_distance\fR units from the center of the aperture disk.
+ This causes objects which are \fIfocal_distance\fR units from the eye point
+ to be in sharp focus.  Note that an 
+ \fIaperture_radius\fR of zero causes a pinhole camera model to be used,
+ and there will be no blurring (this is the default).  Increasing the
+ aperture radius leads to increased blurring.  When using
+ a non-zero aperture radius, it is best to use jittered sampling in order to
+ reduce aliasing effects.
+ .TP
+ \fBfocaldist \fIfocal_distance\fR
+ Specifies the distance, in world units, from the eye point to the
+ focal plane.  Points which lie in this plane will always be in
+ sharp focus.  By keeping
+ \fIaperture_radius\fR constant and changing \fIfocal_distance\fR, it is
+ possible to create a sequence of frames which simulate pulling focus.
+ By default, \fIfocal_distance\fR is equal to the distance from the eye point
+ to the look point.
+ .TP
  \fBmaxdepth \fImaximum_depth\fR
  Controls the maximum depth of the ray tree.  The default is 3, with eye
  rays considered to be of depth zero.
***************
*** 217,226 ****
  \fBsamples \fInum_samples\fR
  Specifies the number of jittered samples.  See SAMPLING for details.
  When specified, this value may be overridden through the use of the
! \fB-S\fR option.  The default value is three.
  .TP
  \fBcontrast \fIred green blue\fR
! Specifies the maximum allowed contrast between samples in a (sub)pixel
  before subdivision takes place.  See SAMPLING for details.
  When specified in the input file, these
  values may be overridden through the use of the \fB-C\fR option.  The
--- 267,276 ----
  \fBsamples \fInum_samples\fR
  Specifies the number of jittered samples.  See SAMPLING for details.
  When specified, this value may be overridden through the use of the
! \fB-S\fR option.  The default value is 3.
  .TP
  \fBcontrast \fIred green blue\fR
! Specifies the maximum contrast allowed between samples in a (sub)pixel
  before subdivision takes place.  See SAMPLING for details.
  When specified in the input file, these
  values may be overridden through the use of the \fB-C\fR option.  The
***************
*** 233,239 ****
  Point sources are specified by a location in world-space
  and produce shadows with sharp edges.  Extended sources are specified
  by a location and a radius.  They produce shadows with "fuzzy" edges
! (penumbrae), but increase ray-tracing time considerably.  Directional
  sources are specified by a direction.
  A maximum of 10 light sources may be defined.
  .PP
--- 283,289 ----
  Point sources are specified by a location in world-space
  and produce shadows with sharp edges.  Extended sources are specified
  by a location and a radius.  They produce shadows with "fuzzy" edges
! (penumbrae), but increase ray tracing time considerably.  Directional
  sources are specified by a direction.
  A maximum of 10 light sources may be defined.
  .PP
***************
*** 262,268 ****
  time is increased substantially.  Rather than tracing one shadow
  ray to a light source, multiple rays
  are traced to various points on the extended source.  The extended source
! is approximated by sampling a square grid light sources.
  See SAMPLING for more details on the
  sampling of extended light sources.
  .TP
--- 312,318 ----
  time is increased substantially.  Rather than tracing one shadow
  ray to a light source, multiple rays
  are traced to various points on the extended source.  The extended source
! is approximated by sampling a square grid of light sources.
  See SAMPLING for more details on the
  sampling of extended light sources.
  .TP
***************
*** 302,311 ****
  specify the diffuse color of the surface.  This color, the
  .I brightness
  component of each light source whose light strikes the surface, and
! dot product of the incoming ray and the surface normal at the point of
  intersection
! determine the color which is added to the color of the ray striking
! the surface.
  .PP
  .I Sr, sg
  and
--- 352,360 ----
  specify the diffuse color of the surface.  This color, the
  .I brightness
  component of each light source whose light strikes the surface, and
! dot product of the incident ray and the surface normal at the point of
  intersection
! determine the color which is added to the color of the incident ray.
  .PP
  .I Sr, sg
  and
***************
*** 330,336 ****
  a reflection ray. The color assigned to that ray will be scaled
  by
  .I refl
! and added to the color of the surface.
  .PP
  .I Transp
  is
--- 379,385 ----
  a reflection ray. The color assigned to that ray will be scaled
  by
  .I refl
! and added to the color of the incident ray.
  .PP
  .I Transp
  is
***************
*** 337,347 ****
  a floating-point number between 0 and 1
  which indicates the transparency of the object.  If non-zero,
  a ray striking the surface will spawn a ray which is transmitted through
! the object,
! and the resulting color of this ray is scaled by
! .I transp
! and added to
! the color of the surface.  The direction of the refraction
  ray is controlled by the
  .I index
  parameter, which indicates the index of refraction of
--- 386,395 ----
  a floating-point number between 0 and 1
  which indicates the transparency of the object.  If non-zero,
  a ray striking the surface will spawn a ray which is transmitted through
! the object.
! The resulting color of this transmitted ray is scaled by
! \fItransp\fR and added to the
! color of the incident ray.  The direction of the transmitted
  ray is controlled by the
  .I index
  parameter, which indicates the index of refraction of
***************
*** 365,373 ****
  .br
  .SH PRIMITIVES
  .PP
! The raytracer is capable of rendering a number of primitive objects.
  Primitives may be specified inside of an object-definition block, in
! which case it is added to the list of primitives belonging to that
  object. In addition, primitives may be defined
  outside of object-definition blocks.  Primitives such as these are
  added to the list of primitives belonging to the World object.  See
--- 413,421 ----
  .br
  .SH PRIMITIVES
  .PP
! The ray tracer is capable of rendering a number of primitive objects.
  Primitives may be specified inside of an object-definition block, in
! which case they are added to the list of primitives belonging to that
  object. In addition, primitives may be defined
  outside of object-definition blocks.  Primitives such as these are
  added to the list of primitives belonging to the World object.  See
***************
*** 379,385 ****
  to this rule are transparent primitives, for which rayshade uses the
  dot product of the normal and the incident ray to determine if the ray
  is entering or exiting the surface, and superquadrics, whose normals
! are never modified due to the nature of the ray/superquadric interesection
  code.  Thus, all non-transparent primitives except superquadrics will in
  effect be double-sided.
  .PP
--- 427,433 ----
  to this rule are transparent primitives, for which rayshade uses the
  dot product of the normal and the incident ray to determine if the ray
  is entering or exiting the surface, and superquadrics, whose normals
! are never modified due to the nature of the ray/superquadric intersection
  code.  Thus, all non-transparent primitives except superquadrics will in
  effect be double-sided.
  .PP
***************
*** 454,468 ****
  while the top will have radius
  .I top_radius.
  .TP
! \fBheightfield \fIfilename\fR
  Reads height field data from \fIfilename\fR and creates a height square
  height field of unit size centered at (0.5, 0.5).  The binary data in
  \fIfilename\fR
  is stored as an initial integer giving the square root of number of data
! points in the file, followed by the data stored as floating-point
  numbers.  The height field is rendered as a surface tessellated by triangles.
  Non-square height fields may be rendered by setting vertex heights to
! less than or equal to -1000.  Triangles which have all vertices less than
  or equal in altitude to this value are not rendered.
  .TP
  \fBbox \fIsurface xcenter ycenter zcenter xsize ysize zsize\fR
--- 502,516 ----
  while the top will have radius
  .I top_radius.
  .TP
! \fBheightfield \fIsurface filename\fR
  Reads height field data from \fIfilename\fR and creates a height square
  height field of unit size centered at (0.5, 0.5).  The binary data in
  \fIfilename\fR
  is stored as an initial integer giving the square root of number of data
! points in the file, followed by altitude (Z) values stored as floating-point
  numbers.  The height field is rendered as a surface tessellated by triangles.
  Non-square height fields may be rendered by setting vertex heights to
! less than or equal to -1000.  Triangles which have any vertex less than
  or equal in altitude to this value are not rendered.
  .TP
  \fBbox \fIsurface xcenter ycenter zcenter xsize ysize zsize\fR
***************
*** 496,502 ****
  the value of
  .I power,
  the closer it will resemble the box (with rounded corners).  A value greater
! than or equal to one is required for reasonable images.  In addition,
  neither transparent superquadrics nor superquadrics viewed from the
  interior will rendered correctly.
  .br
--- 544,550 ----
  the value of
  .I power,
  the closer it will resemble the box (with rounded corners).  A value greater
! than or equal to 1 is required for reasonable images.  In addition,
  neither transparent superquadrics nor superquadrics viewed from the
  interior will rendered correctly.
  .br
***************
*** 536,542 ****
  .I rayshade.
  Primitive definitions and object instantiations which do not appear
  inside an object-definition block are added to this object.  When
! performing raytracing, rays are intersected with the objects that make up
  the World object.
  .PP
  Internally, objects are stored by one of two means.  By default,
--- 584,590 ----
  .I rayshade.
  Primitive definitions and object instantiations which do not appear
  inside an object-definition block are added to this object.  When
! performing ray tracing, rays are intersected with the objects that make up
  the World object.
  .PP
  Internally, objects are stored by one of two means.  By default,
***************
*** 544,550 ****
  The constituents of such an object are stored in a simple
  linked-list.  When a ray is intersected with such an object, the ray
  is tested for intersection with each object in the list.
! While the \fIlist\fR is the default method of object storage, one may
  emphasize this fact in the input file by including the
  .B list
  keyword somewhere within the object-definition block.
--- 592,598 ----
  The constituents of such an object are stored in a simple
  linked-list.  When a ray is intersected with such an object, the ray
  is tested for intersection with each object in the list.
! While the list is the default method of object storage, one may
  emphasize this fact in the input file by including the
  .B list
  keyword somewhere within the object-definition block.
***************
*** 553,566 ****
  The grid's total size
  is calculated by
  .I rayshade
! and is equal to the bounding box of the entire object.
  A grid subdivides the space in which an object lies into an array
  of uniform box-shaped
  .I voxels.
  Each voxel contains a linked-list of objects and primitives which
! lie within that voxel.  When intersecting a ray with an object whose
! constituents are stored in a grid, the ray is traced incrementally from
! voxel-to-voxel, and the ray is intersected with each object in the
  linked list of each voxel that is visited.
  In this way
  the intersection of a ray with a collection of objects is
--- 601,614 ----
  The grid's total size
  is calculated by
  .I rayshade
! and is equal to the bounding box of the object that is engridded.
  A grid subdivides the space in which an object lies into an array
  of uniform box-shaped
  .I voxels.
  Each voxel contains a linked-list of objects and primitives which
! lie within that voxel.  When intersecting a ray with an object which
! is stored in a grid, the ray is traced incrementally from
! voxel-to-voxel, and the ray is tested for intersected against each object in the
  linked list of each voxel that is visited.
  In this way
  the intersection of a ray with a collection of objects is
***************
*** 652,661 ****
  .TP
  \fBbump\fI scale\fR
  applies a random bump map to the surface being textured.  The point of
! intersection is passed to DNoise().  The returned normalized vector,
  weighted by
  .I scale
! is added to the normal vector at the point of intersection.
  .TP
  \fBchecker\fI size surface\fR
  applies a (3D) checkerboard texture to the object being textured.  Every
--- 700,709 ----
  .TP
  \fBbump\fI scale\fR
  applies a random bump map to the surface being textured.  The point of
! intersection is passed to DNoise().  The returned normalized vector is
  weighted by
  .I scale
! and added to the normal vector at the point of intersection.
  .TP
  \fBchecker\fI size surface\fR
  applies a (3D) checkerboard texture to the object being textured.  Every
***************
*** 663,669 ****
  of the named surface.  Every point that falls within an "odd" cube will
  retain its usual surface characteristics.  Be warned that strange effects
  due to roundoff error are possible when the planar surface of an object lies
! in a plane of constant integral values in texture space.
  .TP
  \fBblotch \fIblend_factor surface\fR
  This texture produces a mildly interesting blotchy-looking surface.
--- 711,717 ----
  of the named surface.  Every point that falls within an "odd" cube will
  retain its usual surface characteristics.  Be warned that strange effects
  due to roundoff error are possible when the planar surface of an object lies
! in a plane of constant integral value in texture space.
  .TP
  \fBblotch \fIblend_factor surface\fR
  This texture produces a mildly interesting blotchy-looking surface.
***************
*** 675,682 ****
  .TP
  \fBfbm \fIscale offset H lambda octaves thresh\fR [\fIcolormap\fR]
  This texture generates a sample of discretized fractional Brownian motion (fBm)
! and uses it to modify the diffuse component of an object's color.  If no
! \fIcolormap\fR is named, the sample
  is used to scale the object's diffuse color.
  If a \fIcolormap\fR name is
  given, a 256-entry colormap is read from the named file, and the object
--- 723,730 ----
  .TP
  \fBfbm \fIscale offset H lambda octaves thresh\fR [\fIcolormap\fR]
  This texture generates a sample of discretized fractional Brownian motion (fBm)
! and uses it to modify the diffuse and ambient components of an object's color.
! If no \fIcolormap\fR is named, the sample
  is used to scale the object's diffuse color.
  If a \fIcolormap\fR name is
  given, a 256-entry colormap is read from the named file, and the object
***************
*** 694,707 ****
  output of fBm function.  Any value lower than \fIthresh\fR is set to zero.
  .TP
  \fBfbmbump \fIscale offset H lambda octaves thresh\fR
! This texture is similar to the \fBfBm\fR texture.  Rather modifying the
! color of a surface, \fBfBmBump\fR acts as a bump map.
  .TP
  \fBmarble\fR [\fIcolormap\fR]
  This texture gives a surface a marble-like appearance.  If the name of a
  \fIcolormap\fR file is given, the marble will be colored using the RGB values
! in the colormap.  If no colormap name is given, the diffuse component of
! the object's surface is simply scaled.  One may transform the texture to
  control the density of the marble veins.
  .TP
  \fBwood\fR
--- 742,756 ----
  output of fBm function.  Any value lower than \fIthresh\fR is set to zero.
  .TP
  \fBfbmbump \fIscale offset H lambda octaves thresh\fR
! This texture is similar to the \fBfbm\fR texture.  Rather modifying the
! color of a surface, \fBfbmbump\fR acts as a bump map.
  .TP
  \fBmarble\fR [\fIcolormap\fR]
  This texture gives a surface a marble-like appearance.  If the name of a
  \fIcolormap\fR file is given, the marble will be colored using the RGB values
! in the colormap.  If no colormap name is given, the diffuse and ambient
! components of
! the object's surface are simply scaled.  One may transform the texture to
  control the density of the marble veins.
  .TP
  \fBwood\fR
***************
*** 712,721 ****
  256 lines in length, each line containing three space-separated integers
  ranging from 0 to 255.  The first number on the nth line specifies the red
  component of the nth entry in the colormap, the second number the green 
! component, and the third the blue.
  .PP
  It is important to note that more than one texture may be applied to
! a point at any time.  In addition to being able to apply more than
  one texture directly (by supplying multiple "texturing information" lines for
  a single object), one may instantiate textured objects which, in turn,
  may be textured or contain instances of objects which are textured, and so on.
--- 761,774 ----
  256 lines in length, each line containing three space-separated integers
  ranging from 0 to 255.  The first number on the nth line specifies the red
  component of the nth entry in the colormap, the second number the green 
! component, and the third the blue.  The values in the colormap are normalized
! before being used in texturing functions.
! Textures which make use of colormaps
! generally compute an index into the colormap and use the corresponding
! entry to scale the ambient and diffuse components of a surface's color.
  .PP
  It is important to note that more than one texture may be applied to
! an object at any time.  In addition to being able to apply more than
  one texture directly (by supplying multiple "texturing information" lines for
  a single object), one may instantiate textured objects which, in turn,
  may be textured or contain instances of objects which are textured, and so on.
***************
*** 724,738 ****
  .PP
  .I Rayshade
  has the capability of including several kinds of atmospheric effects
! when rendering an image.  Currently, one such effect is available:
  .TP
  \fBfog\fI thinness red green blue\fR
  Add global exponential fog with the specified \fIthinness\fR and color.
  Fog is simulated by blending the color of the fog with the color of
! each ray.  The amount of fog color added to a ray is a function of
! the logarithm of the
! distance from the ray origin to the point of intersection divided by
! \fIthinness\fR.
  .br
  .SH "SAMPLING"
  .PP
--- 777,803 ----
  .PP
  .I Rayshade
  has the capability of including several kinds of atmospheric effects
! when rendering an image.  Currently, two such effects are available:
  .TP
  \fBfog\fI thinness red green blue\fR
  Add global exponential fog with the specified \fIthinness\fR and color.
  Fog is simulated by blending the color of the fog with the color of
! each ray.  The amount of fog color blended into a ray color is an exponential
! function of the distance from the ray origin to the point of intersection
! divided by \fIthinness\fR.  If the distance divided by \fIthinness\fR
! is equal to 1, a ray's new color will be half of the fog color plus half its
! original color.
! .TP
! \fBmist\fI red green blue trans.red trans.green trans.blue zero scale\fR
! Add global low-altitude mist of the specified color.  The color of
! a ray is modulated by a fog with density which varies linearly with
! the difference in altitude (Z coordinate) between the ray origin and
! the point of intersection.  The three
! trans values specify the transmissivity (thinness) of the mist for
! each of the red, green and blue channels.  The base altitude of the
! mist is given by \fIzero\fR, and the apparent height of the mist can
! be controlled by \fIscale\fR, which is used to scale the difference in
! altitude.
  .br
  .SH "SAMPLING"
  .PP
***************
*** 748,754 ****
  the \fBcontrast\fR command.
  There are separate
  thresholds for the red, green, and blue channels.  If the contrast
! in any of the three is greater than the appropriate treshold value,
  the pixel is subdivided.
  The pixel-subdivision process is repeated until either
  the samples' contrast is less than the threshold or the maximum pixel
--- 813,819 ----
  the \fBcontrast\fR command.
  There are separate
  thresholds for the red, green, and blue channels.  If the contrast
! in any of the three is greater than the appropriate threshold value,
  the pixel is subdivided.
  The pixel-subdivision process is repeated until either
  the samples' contrast is less than the threshold or the maximum pixel
***************
*** 764,770 ****
  \fB-S\fR option.  The integer following this option specifies the square
  root of the number of regions.
  .PP
! Each area light source is, in effect, approximated by a square grid
  of light
  sources.  The length of each side of the square is equal to the diameter
  of the extended source.
--- 829,835 ----
  \fB-S\fR option.  The integer following this option specifies the square
  root of the number of regions.
  .PP
! Each extended light source is, in effect, approximated by a square grid
  of light
  sources.  The length of each side of the square is equal to the diameter
  of the extended source.
***************
*** 830,836 ****
  .IN -8
  .fi
  .PP
! Passing this file to
  .I rayshade
  will result in an image of a red reflective sphere sitting on a white
  ground-plane being written to the standard output.  Note that in this case,
--- 895,901 ----
  .IN -8
  .fi
  .PP
! Passing this input to
  .I rayshade
  will result in an image of a red reflective sphere sitting on a white
  ground-plane being written to the standard output.  Note that in this case,
***************
*** 908,914 ****
  .fi
  could be used to define a very primitive truck-like object.
  .br
! .SH "MINIMIZING RAYTRACING TIME"
  .PP
  Ray tracing is a computationally intensive process, and rendering
  complex scenes can take hours of CPU time, even on relatively powerful
--- 973,979 ----
  .fi
  could be used to define a very primitive truck-like object.
  .br
! .SH "RENDERING HINTS"
  .PP
  Ray tracing is a computationally intensive process, and rendering
  complex scenes can take hours of CPU time, even on relatively powerful
***************
*** 920,926 ****
  of the image to be rendered.  The
  .B \-P
  option may be used to reduce the maximum pixel subdivision level.
! A maximum level of 0 will speed raytracing up considerably, but will result
  in obvious aliasing in the image.  By default, a pixel will be subdivided
  a maximum of one time, giving a maximum of nine rays per pixel total.
  .PP 
--- 985,991 ----
  of the image to be rendered.  The
  .B \-P
  option may be used to reduce the maximum pixel subdivision level.
! A maximum level of 0 will speed ray tracing considerably, but will result
  in obvious aliasing in the image.  By default, a pixel will be subdivided
  a maximum of one time, giving a maximum of nine rays per pixel total.
  .PP 
***************
*** 941,949 ****
  .B maxdepth
  to a small number.  If set to 0, no reflection or
  refraction rays will be traced. 
! Lastly, removing all light sources
! will cause no shadow rays to be traced, but will result in a flat-looking
! image.
  .PP
  In addition, judicious use of the \fBgrid\fR command can reduce rendering
  times substantially.
--- 1006,1012 ----
  .B maxdepth
  to a small number.  If set to 0, no reflection or
  refraction rays will be traced. 
! Lastly, using the \fB-n\fR option will cause no shadow rays to be traced.
  .PP
  In addition, judicious use of the \fBgrid\fR command can reduce rendering
  times substantially.
***************
*** 950,955 ****
--- 1013,1024 ----
  However, if an object consists of a relatively small number of simple objects,
  it will likely take less time to simply check for intersection with
  each element of the object than to trace a ray through a grid.
+ .PP
+ The C pre-processor can be used to make the creation and managing of input
+ files much easier.  For example, one can create "libraries" of useful colors,
+ objects, and viewing parameters by using #define and #include.  To use such
+ input files, run the C pre-processor on the file, and pipe the resulting
+ text to rayshade.
  .br
  .SH FILES
  .nf
***************
*** 960,966 ****
  .I Rayshade
  had its beginnings as an
  "introductory" public-domain
! raytracer written by Roman Kuchkuda.  Vestiges of his code may be found
  in rayshade, particularly in the names of variables and the superquadric
  code.
  The first version of
--- 1029,1035 ----
  .I Rayshade
  had its beginnings as an
  "introductory" public-domain
! ray tracer written by Roman Kuchkuda.  Vestiges of his code may be found
  in rayshade, particularly in the names of variables and the superquadric
  code.
  The first version of
***************
*** 972,978 ****
  was written during the fall of 1988 by Craig Kolb.
  The Noise() and DNoise() routines which form the basis of many
  of the texturing functions were written by Robert Skinner and Ken
! Musgrave.
  .br
  .SH "CAVEATS"
  .PP
--- 1041,1047 ----
  was written during the fall of 1988 by Craig Kolb.
  The Noise() and DNoise() routines which form the basis of many
  of the texturing functions were written by Robert Skinner and Ken
! Musgrave.  The depth of field code appears courtesy of Rodney G. Bogart.
  .br
  .SH "CAVEATS"
  .PP
***************
*** 994,1000 ****
  The "Total memory allocated" statistic is the total space allocated by
  calls to malloc.  It is \fInot\fR the memory high-water mark.  After
  the input file is processed, memory is only allocated when refraction
! occurs (to push media onto a stack) and when raytracing height fields
  (to dynamically allocate triangles).
  .PP
  The image produced will always be 24 bits deep.
--- 1063,1069 ----
  The "Total memory allocated" statistic is the total space allocated by
  calls to malloc.  It is \fInot\fR the memory high-water mark.  After
  the input file is processed, memory is only allocated when refraction
! occurs (to push media onto a stack) and when ray tracing height fields
  (to dynamically allocate triangles).
  .PP
  The image produced will always be 24 bits deep.

Index: src/raytrace.c
*** src/raytrace.c.old	Thu Dec  7 23:21:04 1989
--- src/raytrace.c	Thu Dec  7 23:21:06 1989
***************
*** 18,26 ****
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: raytrace.c,v 3.0.1.2 89/11/16 20:35:30 craig Exp Locker: craig $
   *
   * $Log:	raytrace.c,v $
   * Revision 3.0.1.2  89/11/16  20:35:30  craig
   * patch1: ShadeRay is now called on background rays.
   * 
--- 18,35 ----
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: raytrace.c,v 3.0.1.5 89/12/07 22:55:25 craig Exp $
   *
   * $Log:	raytrace.c,v $
+  * Revision 3.0.1.5  89/12/07  22:55:25  craig
+  * patch2: Renamed utime and stime to avoid name clashes.
+  * 
+  * Revision 3.0.1.4  89/12/02  16:41:46  craig
+  * patch2: Added ReportFreq, reporting of total CPU & split times.
+  * 
+  * Revision 3.0.1.3  89/12/02  14:42:37  craig
+  * patch2: Added call to focus_blur_ray() to support depth of field.
+  * 
   * Revision 3.0.1.2  89/11/16  20:35:30  craig
   * patch1: ShadeRay is now called on background rays.
   * 
***************
*** 61,66 ****
--- 70,76 ----
  int	*SampleNumbers;
  int	SampleNumber;
  int	StartLine = UNSET;
+ int	ReportFreq;			/* Frequency of status report */
  double	RedContrast = UNSET, GreenContrast = UNSET, BlueContrast = UNSET;
  double	SampleSpacing;
  
***************
*** 92,98 ****
  {
  #ifdef LINDA
  	extern unsigned long primtests[], primhits[];
! 	extern double utime, stime;
  	extern unsigned long EyeRays, ShadowRays, ReflectRays, RefractRays,
  			CacheWorked, CacheFailed, ShadowHits, SuperSampled,
  			BVTests, HitRays;
--- 102,108 ----
  {
  #ifdef LINDA
  	extern unsigned long primtests[], primhits[];
! 	extern double usertime, systime;
  	extern unsigned long EyeRays, ShadowRays, ReflectRays, RefractRays,
  			CacheWorked, CacheFailed, ShadowHits, SuperSampled,
  			BVTests, HitRays;
***************
*** 143,150 ****
  			primhits[j] += hittmp[j];
  		}
  		in ("timing", ? utmp, ? stmp);
! 		utime += utmp / (double)Workers;
! 		stime += stmp / (double)Workers;
  		in("worker", ? int);
  	}
  #endif
--- 153,160 ----
  			primhits[j] += hittmp[j];
  		}
  		in ("timing", ? utmp, ? stmp);
! 		usertime += utmp / (double)Workers;
! 		systime += stmp / (double)Workers;
  		in("worker", ? int);
  	}
  #endif
***************
*** 160,165 ****
--- 170,178 ----
  	extern unsigned long EyeRays;
  #ifdef LINDA
  	extern int VerboseWorker;
+ #else
+ 	double usertime, systime, lasttime;
+ 	extern int Verbose;
  #endif
  
  	switch (JitSamples) {
***************
*** 205,211 ****
  		in("result", y, ? out_buf:);
  		if (VerboseWorker)
  			fprintf(stderr,"Supervisor: inned %d\n",y);
! 		if (y % 10 == 0)
  			fprintf(fstats, "Finished line %d.\n",y);
  		fflush(fstats);
  		outline(out_buf);
--- 218,224 ----
  		in("result", y, ? out_buf:);
  		if (VerboseWorker)
  			fprintf(stderr,"Supervisor: inned %d\n",y);
! 		if (y % ReportFreq == 0)
  			fprintf(fstats, "Finished line %d.\n",y);
  		fflush(fstats);
  		outline(out_buf);
***************
*** 214,225 ****
  	/*
  	 * Trace each scanline, writing results to output file.
  	 */
  	for (y = StartLine; y >= 0; y--) {
  		trace_jit_line(y, out_buf);
  		outline(out_buf);
! 		if (y % 10 == 0) {
! 			fprintf(fstats,"Finished line %d (%ld rays)\n",y,
  							EyeRays);
  			fflush(fstats);
  		}
  	}
--- 227,251 ----
  	/*
  	 * Trace each scanline, writing results to output file.
  	 */
+ 	lasttime = 0;
  	for (y = StartLine; y >= 0; y--) {
  		trace_jit_line(y, out_buf);
  		outline(out_buf);
! 		if (y % ReportFreq == 0) {
! 			fprintf(fstats,"Finished line %d (%ld rays",y,
  							EyeRays);
+ 			if (Verbose) {
+ 				/*
+ 				 * Report total CPU and split times.
+ 				 */
+ 				get_cpu_time(&usertime, &systime);
+ 				fprintf(fstats,", %2.2lf sec,",
+ 						usertime+systime);
+ 				fprintf(fstats," %2.2lf split",
+ 						usertime+systime-lasttime);
+ 				lasttime = usertime+systime;
+ 			}
+ 			fprintf(fstats,")\n");
  			fflush(fstats);
  		}
  	}
***************
*** 270,276 ****
  	extern unsigned long EyeRays;
  	extern FILE *fstats;
  #ifdef LINDA
! 	extern int maxlevel, VerboseWorker;
  #endif
  
  	/*
--- 296,305 ----
  	extern unsigned long EyeRays;
  	extern FILE *fstats;
  #ifdef LINDA
! 	extern int VerboseWorker;
! #else
! 	double usertime, systime, lasttime;
! 	extern int Verbose;
  #endif
  
  	/*
***************
*** 338,346 ****
  		while (inp("result", line, ? out_buf:)) {
  			if (VerboseWorker)
  				fprintf(stderr,"Supervisor: inned %d\n",line);
! 			if (line % 10 == 0)
  				fprintf(fstats, "Finished line %d.\n",line);
! 			fflush(fstats);
  			outline(out_buf);
  			if (--line < 0)
  				break;
--- 367,376 ----
  		while (inp("result", line, ? out_buf:)) {
  			if (VerboseWorker)
  				fprintf(stderr,"Supervisor: inned %d\n",line);
! 			if (line % ReportFreq == 0) {
  				fprintf(fstats, "Finished line %d.\n",line);
! 				fflush(fstats);
! 			}
  			outline(out_buf);
  			if (--line < 0)
  				break;
***************
*** 349,354 ****
--- 379,385 ----
  #else
  	line = StartLine + 1;
  	trace_line(line, &pixel_buf[line & 01][0]);
+ 	lasttime = 0;
  	/*
  	 * Work bottom-to-top, as that's the way Utah-raster wants to
  	 * operate.
***************
*** 359,367 ****
  				     pixel_buf[(line+1) & 01],
  				     out_buf);
  		outline(out_buf);
! 		if(line % 10 == 0) {
! 			fprintf(fstats,"Finished line %d (%ld rays)\n",line,
  								EyeRays);
  			fflush(fstats);
  		}
  	}
--- 390,410 ----
  				     pixel_buf[(line+1) & 01],
  				     out_buf);
  		outline(out_buf);
! 		if(line % ReportFreq == 0) {
! 			fprintf(fstats,"Finished line %d (%ld rays",line,
  								EyeRays);
+ 			if (Verbose) {
+ 				/*
+ 				 * Report total CPU and split times.
+ 				 */
+ 				get_cpu_time(&usertime, &systime);
+ 				fprintf(fstats,", %2.2lf sec,",
+ 						usertime+systime);
+ 				fprintf(fstats," %2.2lf split",
+ 						usertime+systime-lasttime);
+ 				lasttime = usertime+systime;
+ 			}
+ 			fprintf(fstats,")\n");
  			fflush(fstats);
  		}
  	}
***************
*** 499,504 ****
--- 542,548 ----
  	double dist;
  	HitInfo hitinfo;
  	extern Vector scrnx, scrny;
+ 	extern double aperture;
  	extern unsigned long EyeRays;
  	extern double TraceRay();
  
***************
*** 511,516 ****
--- 555,568 ----
  	TopRay.dir.z = firstray.z + x*scrnx.z - y*scrny.z;
  
  	(void)normalize(&TopRay.dir);
+ 
+ 	if (aperture > 0.0) {
+ 		/*
+ 		 * If the aperture is open, adjust the initial ray
+ 		 * to account for depth of field.  
+ 		 */
+ 		focus_blur_ray(&TopRay);
+ 	}
  
  	/*
  	 * Do the actual ray trace.

Index: src/setup.c
*** src/setup.c.old	Thu Dec  7 23:21:12 1989
--- src/setup.c	Thu Dec  7 23:21:13 1989
***************
*** 18,26 ****
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: setup.c,v 3.0 89/10/27 02:06:03 craig Exp $
   *
   * $Log:	setup.c,v $
   * Revision 3.0  89/10/27  02:06:03  craig
   * Baseline for first official release.
   * 
--- 18,29 ----
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: setup.c,v 3.0.1.1 89/12/02 16:52:33 craig Exp $
   *
   * $Log:	setup.c,v $
+  * Revision 3.0.1.1  89/12/02  16:52:33  craig
+  * patch2: Added code to set default value for ReportFreq.
+  * 
   * Revision 3.0  89/10/27  02:06:03  craig
   * Baseline for first official release.
   * 
***************
*** 40,46 ****
   */
  setup()
  {
! 	extern int maxlevel;
  	extern double hfov, vfov;
  	extern Vector eyep, lookp, up;
  	extern Object *World;
--- 43,49 ----
   */
  setup()
  {
! 	extern int maxlevel, ReportFreq;
  	extern double hfov, vfov;
  	extern Vector eyep, lookp, up;
  	extern Object *World;
***************
*** 80,85 ****
--- 83,89 ----
  	up.x = UPX;
  	up.y = UPY;
  	up.z = UPZ;
+ 	ReportFreq = REPORTFREQ;
  
  	/*
  	 * Kinda yicky, but compatible.

Index: src/sphere.c
*** src/sphere.c.old	Thu Dec  7 23:21:19 1989
--- src/sphere.c	Thu Dec  7 23:21:20 1989
***************
*** 18,26 ****
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: sphere.c,v 3.0 89/10/27 02:06:04 craig Exp $
   *
   * $Log:	sphere.c,v $
   * Revision 3.0  89/10/27  02:06:04  craig
   * Baseline for first official release.
   * 
--- 18,29 ----
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: sphere.c,v 3.0.1.1 89/12/06 16:33:35 craig Exp $
   *
   * $Log:	sphere.c,v $
+  * Revision 3.0.1.1  89/12/06  16:33:35  craig
+  * patch2: Added calls to new error/warning routines.
+  * 
   * Revision 3.0  89/10/27  02:06:04  craig
   * Baseline for first official release.
   * 
***************
*** 43,54 ****
  	Sphere       *sphere;
  	Object *newobj;
  	Primitive *prim;
- 	extern int Quiet, yylineno;
  
  	if (r < EPSILON) {
! 		if (!Quiet)
! 			fprintf(stderr,"Degenerate sphere (line %d)\n",
! 							yylineno);
  		return (Object *)0;
  	}
  
--- 46,54 ----
  	Sphere       *sphere;
  	Object *newobj;
  	Primitive *prim;
  
  	if (r < EPSILON) {
! 		yywarning("Degenerate sphere.\n");
  		return (Object *)0;
  	}
  

Index: src/surface.c
*** src/surface.c.old	Thu Dec  7 23:21:25 1989
--- src/surface.c	Thu Dec  7 23:21:26 1989
***************
*** 18,26 ****
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: surface.c,v 3.0 89/10/27 02:06:05 craig Exp $
   *
   * $Log:	surface.c,v $
   * Revision 3.0  89/10/27  02:06:05  craig
   * Baseline for first official release.
   * 
--- 18,29 ----
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: surface.c,v 3.0.1.1 89/12/06 16:33:11 craig Exp $
   *
   * $Log:	surface.c,v $
+  * Revision 3.0.1.1  89/12/06  16:33:11  craig
+  * patch2: Added calls to new error/warning routines.
+  * 
   * Revision 3.0  89/10/27  02:06:05  craig
   * Baseline for first official release.
   * 
***************
*** 50,56 ****
  	 * Complain if named surface already exists.
  	 */
  	if ((stmp = get_surface(name)) != (Surface *)0)
! 		yyerror("Surface redefined.");
  
  	stmp = (Surface *)Malloc(sizeof(Surface));
  	stmp->name = strsave(name);
--- 53,59 ----
  	 * Complain if named surface already exists.
  	 */
  	if ((stmp = get_surface(name)) != (Surface *)0)
! 		yyerror("Surface \"%s\" redefined.", name);
  
  	stmp = (Surface *)Malloc(sizeof(Surface));
  	stmp->name = strsave(name);
***************
*** 91,97 ****
  
  	stmp = get_surface(name);
  	if (stmp == (Surface *)0)
! 		yyerror("Undefined surface.");
  
  	return stmp;
  }
--- 94,100 ----
  
  	stmp = get_surface(name);
  	if (stmp == (Surface *)0)
! 		yyerror("Undefined surface \"%s\".", name);
  
  	return stmp;
  }

Index: src/texture.c
*** src/texture.c.old	Thu Dec  7 23:21:40 1989
--- src/texture.c	Thu Dec  7 23:21:41 1989
***************
*** 18,26 ****
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: texture.c,v 3.0 89/10/27 02:06:05 craig Exp $
   *
   * $Log:	texture.c,v $
   * Revision 3.0  89/10/27  02:06:05  craig
   * Baseline for first official release.
   * 
--- 18,33 ----
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: texture.c,v 3.0.1.2 89/12/06 16:33:50 craig Exp $
   *
   * $Log:	texture.c,v $
+  * Revision 3.0.1.2  89/12/06  16:33:50  craig
+  * patch2: Added calls to new error/warning routines.
+  * 
+  * Revision 3.0.1.1  89/11/27  18:36:54  craig
+  * patch2: Removed hardcoded constants in calculation of ambient
+  * patch2: component in several textures.
+  * 
   * Revision 3.0  89/10/27  02:06:05  craig
   * Baseline for first official release.
   * 
***************
*** 132,139 ****
  	surf->diff.r *= red;
  	surf->diff.g *= grn;
  	surf->diff.b *= blu;
! 
! 	ScaleColor(0.3, surf->diff, &surf->amb);
  }
  
  /*
--- 139,147 ----
  	surf->diff.r *= red;
  	surf->diff.g *= grn;
  	surf->diff.b *= blu;
! 	surf->amb.r *= red;
! 	surf->amb.g *= grn;
! 	surf->amb.b *= blu;
  }
  
  /*
***************
*** 271,278 ****
  		index = 255. * val;
  		if (index > 255) index = 255;
  		if (index < 0) index = 0;
! 		surf->diff = text->colormap[index];
! 		ScaleColor(.2, surf->diff, &surf->amb);
  	} else {
  		ScaleColor(val, surf->diff, &surf->diff);
  		ScaleColor(val, surf->amb, &surf->amb);
--- 279,290 ----
  		index = 255. * val;
  		if (index > 255) index = 255;
  		if (index < 0) index = 0;
! 		surf->diff.r *= text->colormap[index].r;
! 		surf->diff.g *= text->colormap[index].g;
! 		surf->diff.b *= text->colormap[index].b;
! 		surf->amb.r *= text->colormap[index].r;
! 		surf->amb.g *= text->colormap[index].g;
! 		surf->amb.b *= text->colormap[index].b;
  	} else {
  		ScaleColor(val, surf->diff, &surf->diff);
  		ScaleColor(val, surf->amb, &surf->amb);
***************
*** 341,347 ****
  	val = Marble(pos);
  	if (text->colormap) {
  		index = (int)(255. * val);
! 		surf->diff = text->colormap[index];
  	} else {
  		ScaleColor(val, surf->amb, &surf->amb);
  		ScaleColor(val, surf->diff, &surf->diff);
--- 353,364 ----
  	val = Marble(pos);
  	if (text->colormap) {
  		index = (int)(255. * val);
! 		surf->diff.r *= text->colormap[index].r;
! 		surf->diff.g *= text->colormap[index].g;
! 		surf->diff.b *= text->colormap[index].b;
! 		surf->amb.r *= text->colormap[index].r;
! 		surf->amb.g *= text->colormap[index].g;
! 		surf->amb.b *= text->colormap[index].b;
  	} else {
  		ScaleColor(val, surf->amb, &surf->amb);
  		ScaleColor(val, surf->diff, &surf->diff);
***************
*** 359,365 ****
  
  	fp = fopen(filename, "r");
  	if (fp == (FILE *)NULL)
! 		yyerror("Cannot open colormap file.");
  
  	map = (Color *)Calloc(256, sizeof(Color));
  
--- 376,382 ----
  
  	fp = fopen(filename, "r");
  	if (fp == (FILE *)NULL)
! 		yyerror("Cannot open colormap file \"%s\".\n", filename);
  
  	map = (Color *)Calloc(256, sizeof(Color));
  

Index: src/viewing.c
*** src/viewing.c.old	Thu Dec  7 23:21:53 1989
--- src/viewing.c	Thu Dec  7 23:21:54 1989
***************
*** 18,26 ****
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: viewing.c,v 3.0.1.1 89/11/16 18:24:30 craig Exp Locker: craig $
   *
   * $Log:	viewing.c,v $
   * Revision 3.0.1.1  89/11/16  18:24:30  craig
   * patch1: Fixed calculation of dist in Stereo mode.
   * 
--- 18,33 ----
   * name of the person performing the modification, the date of modification,
   * and the reason for such modification.
   *
!  * $Id: viewing.c,v 3.0.1.3 89/12/02 14:38:37 craig Exp $
   *
   * $Log:	viewing.c,v $
+  * Revision 3.0.1.3  89/12/02  14:38:37  craig
+  * patch2: Added depth of field code, courtesy of Rodney G. Bogart.
+  * 
+  * Revision 3.0.1.2  89/11/27  19:07:49  craig
+  * patch2: Changed calculation of scrny when NORLE is defined so images
+  * patch2: will be rendered top-to-bottom.
+  * 
   * Revision 3.0.1.1  89/11/16  18:24:30  craig
   * patch1: Fixed calculation of dist in Stereo mode.
   * 
***************
*** 34,54 ****
  #include "typedefs.h"
  #include "funcdefs.h"
  
  Vector lookp, eyep, up, firstray, scrnx, scrny;
  double vfov, hfov, Separation;
  int Xres = UNSET, Yres = UNSET, Stereo;
  viewing()
  {
  	Vector gaze;
! 	double dist, magnitude;
  
  	vecsub(lookp, eyep, &gaze);
  	firstray = gaze;
  
  	dist = normalize(&gaze);
! 	(void)crossp(&scrnx, &gaze, &up);
! 	(void)crossp(&scrny, &scrnx, &gaze);
! 	dist *= 2.0;
  
  	/*
  	 * Add stereo separation if desired.
--- 41,63 ----
  #include "typedefs.h"
  #include "funcdefs.h"
  
+ Vector scrni, scrnj;		/* Unit vectors of screen plane. */
  Vector lookp, eyep, up, firstray, scrnx, scrny;
  double vfov, hfov, Separation;
+ double aperture = 0., focaldist = UNSET;
  int Xres = UNSET, Yres = UNSET, Stereo;
+ 
  viewing()
  {
  	Vector gaze;
! 	double magnitude, dist;
  
  	vecsub(lookp, eyep, &gaze);
  	firstray = gaze;
  
  	dist = normalize(&gaze);
! 	(void)crossp(&scrni, &gaze, &up);
! 	(void)crossp(&scrnj, &scrni, &gaze);
  
  	/*
  	 * Add stereo separation if desired.
***************
*** 58,83 ****
  			magnitude = -.5 * Separation;
  		else
  			magnitude = .5 * Separation;
! 		eyep.x += magnitude * scrnx.x;
! 		eyep.y += magnitude * scrnx.y;
! 		eyep.z += magnitude * scrnx.z;
  		vecsub(lookp, eyep, &firstray);
  		gaze = firstray;
! 		dist = 2. * normalize(&gaze);
! 		(void)crossp(&scrnx, &gaze, &up);
! 		(void)crossp(&scrny, &scrnx, &gaze);
  	}
  
! 	magnitude = dist * tan(deg2rad(0.5*hfov)) / Xres;
! 	scrnx.x *= magnitude;
! 	scrnx.y *= magnitude;
! 	scrnx.z *= magnitude;
! 	magnitude = dist * tan(deg2rad(0.5*vfov)) / Yres;
! 	scrny.x *= magnitude;
! 	scrny.y *= magnitude;
! 	scrny.z *= magnitude;
  
  	firstray.x += 0.5*Yres*scrny.x - 0.5*Xres*scrnx.x;
  	firstray.y += 0.5*Yres*scrny.y - 0.5*Xres*scrnx.y;
  	firstray.z += 0.5*Yres*scrny.z - 0.5*Xres*scrnx.z;
  }
--- 67,162 ----
  			magnitude = -.5 * Separation;
  		else
  			magnitude = .5 * Separation;
! 		eyep.x += magnitude * scrni.x;
! 		eyep.y += magnitude * scrni.y;
! 		eyep.z += magnitude * scrni.z;
  		vecsub(lookp, eyep, &firstray);
  		gaze = firstray;
! 		dist = normalize(&gaze);
! 		(void)crossp(&scrni, &gaze, &up);
! 		(void)crossp(&scrnj, &scrni, &gaze);
  	}
  
! 	magnitude = 2. * dist * tan(deg2rad(0.5*hfov)) / Xres;
! 	scrnx.x = scrni.x * magnitude;
! 	scrnx.y = scrni.y * magnitude;
! 	scrnx.z = scrni.z * magnitude;
! 	magnitude = 2. * dist * tan(deg2rad(0.5*vfov)) / Yres;
! #ifdef NORLE
! 	magnitude *= -1;
! #endif
! 	scrny.x = scrnj.x * magnitude;
! 	scrny.y = scrnj.y * magnitude;
! 	scrny.z = scrnj.z * magnitude;
  
  	firstray.x += 0.5*Yres*scrny.x - 0.5*Xres*scrnx.x;
  	firstray.y += 0.5*Yres*scrny.y - 0.5*Xres*scrnx.y;
  	firstray.z += 0.5*Yres*scrny.z - 0.5*Xres*scrnx.z;
+ 
+ 	if (focaldist == UNSET)
+ 		focaldist = dist;
+ }
+ 
+ /*
+  * Depth of field code courtesy of Rodney G. Bogart.
+  *
+  * Adjust the initial ray to account for an aperture and a focal
+  * distance.  The ray argument is assumed to be an initial ray, and
+  * always reset to the eye point.  It is assumed to be unit length.
+  */
+ focus_blur_ray(ray)
+ Ray *ray;
+ {
+ 	Vector circle_point, aperture_inc;
+ 	/*
+ 	 * Find a point on a unit circle and scale by aperture size.
+ 	 * This simulates rays passing thru different parts of the aperture.
+ 	 * Treat the point as a vector and rotate it so the circle lies
+ 	 * in the plane of the screen.  Add the aperture increment to the
+ 	 * starting position of the ray.  Stretch the ray to be focaldist 
+ 	 * in length.  Subtract the aperture increment from the end of the
+ 	 * long ray.  This insures that the ray heads toward a point at
+ 	 * the specified focus distance, so that point will be in focus.
+ 	 * Normalize the ray, and that's it.  Really.
+ 	 */
+ 	unit_circle_point(&circle_point);
+ 	veccomb(aperture * circle_point.x, scrni,
+ 		    aperture * circle_point.y, scrnj,
+ 		    &aperture_inc);
+ 	vecadd(aperture_inc, eyep, &(ray->pos));
+ 	scalar_prod(focaldist, ray->dir, &(ray->dir));
+ 	vecsub(ray->dir, aperture_inc, &(ray->dir));
+ 	normalize(&ray->dir);
+ }
+ 
+ /*
+  * Find a point on a unit circle which is separated from other random
+  * points by some jitter spacing.
+  *
+  * It should do the above, but the temporary hack below just finds a
+  * jittered point in a unit square.
+  */
+ unit_circle_point(pnt)
+ Vector *pnt;
+ {
+ 	/*
+ 	 * This picks a random point on a -1 to 1 square.  The jitter stuff
+ 	 * is correct enough to avoid excessive noise.  An extremely blurry
+ 	 * bright highlight will look squarish, not roundish.  Sorry.
+ 	 */
+ 	double jit;
+ 	extern double SampleSpacing;
+ 	extern int Jittered, JitSamples, SampleNumber;
+ 
+ 	if (Jittered) {
+ 		jit = 2. * SampleSpacing;
+ 
+ 		pnt->x = nrand()*jit - 1.0 + (SampleNumber % JitSamples) * jit;
+ 		pnt->y = nrand()*jit - 1.0 + (SampleNumber / JitSamples) * jit;
+ 		pnt->z = 0.0;
+ 	} else {
+ 		pnt->x = nrand() * 2.0 - 1.0;
+ 		pnt->y = nrand() * 2.0 - 1.0;
+ 		pnt->z = 0.0;
+ 	}
  }



-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list