home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
GRAPHICS
/
rayshade.lzh
/
viewing.c
< prev
next >
Wrap
Text File
|
1990-10-01
|
5KB
|
166 lines
/*
* viewing.c
*
* Copyright (C) 1989, Craig E. Kolb
*
* This software may be freely copied, modified, and redistributed,
* provided that this copyright notice is preserved on all copies.
*
* There is no warranty or other guarantee of fitness for this software,
* it is provided solely . Bug reports or fixes may be sent
* to the author, who may or may not act on them as he desires.
*
* You may not include this software in a program or other software product
* without supplying the source, or without informing the end-user that the
* source is available for no extra charge.
*
* If you modify this software, you should include a notice giving the
* name of the person performing the modification, the date of modification,
* and the reason for such modification.
*
* $Id: viewing.c,v 3.0.1.4 90/04/04 18:59:54 craig Exp $
*
* $Log: viewing.c,v $
* Revision 3.0.1.4 90/04/04 18:59:54 craig
* patch5: Lint removal.
*
* 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.
*
* Revision 3.0 89/10/27 02:06:08 craig
* Baseline for first official release.
*
*/
#include <math.h>
#include <stdio.h>
#include "constants.h"
#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.
*/
if (Stereo) {
if (Stereo == LEFT)
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));
(void)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;
}
}