File: CastRays.mesa
Last edited by Bier on August 19, 1983 11:40 am
Author: Eric Bier in the summer of 1982
Contents: The ray casting (as opposed to tree building) part of the CSG package. CSG.mesa builds the trees
DIRECTORY
CoordSys,
CSG,
DisplayList3d,
Graphics,
GraphicsColor,
IO,
Matrix3d,
Rope,
Shading,
SV2d,
SVBoundBox,
SVVector3d;
CastRays: DEFINITIONS =
BEGIN
BoundBox: TYPE = REF BoundBoxObj;
BoundBoxObj: TYPE = SVBoundBox.BoundBoxObj;
Camera: TYPE = DisplayList3d.Camera;
Color: TYPE = GraphicsColor.Color;
CoordSystem: TYPE = REF CoordSysObj;
CoordSysObj: TYPE = CoordSys.CoordSysObj;
Point2d: TYPE = SV2d.Point2d;
Point3d: TYPE = Matrix3d.Point3d;
Vector: TYPE = SVVector3d.Vector;
Surface: TYPE = CSG.Surface; -- REF ANY;
CSGTree: TYPE = REF CSGTreeObj;
CSGTreeObj: TYPE = CSG.CSGTreeObj;
maxSceneDepth: NAT = 20;
PointSetOp: TYPE = CSG.PointSetOp;
{union, intersection, difference}
ParameterArray: TYPE = CSG.ParameterArray; -- ARRAY [1..maxSceneDepth] OF REAL;
SurfaceArray: TYPE = REF SurfaceArrayObj;
SurfaceArrayObj: TYPE = CSG.SurfaceArrayObj;
ARRAY [1..maxSurfacesPerObject] OF Surface;
InOutArray: TYPE = CSG.InOutArray; -- ARRAY [1..maxSceneDepth] OF BOOL;
NormalArray: TYPE = CSG.NormalArray; -- ARRAY [1..maxSceneDepth] OF Vector;
PrimitiveArray: TYPE = CSG.PrimitiveArray; -- ARRAY [1..maxSurfacesPerObject] OF Primitive;
Ray: TYPE = REF RayObj;
RayObj: TYPE = CSG.RayObj;
Classification: TYPE = REF ClassificationObj;
ClassificationObj: TYPE = CSG.ClassificationObj;
LightSourceList: TYPE = Shading.LightSourceList;
RayCast: PROC [cameraPoint: Point2d, sceneRay: Ray, node: REF ANY, makeStream: BOOLFALSE, f: IO.STREAMNIL, indent: NAT ← 0] RETURNS [class: Classification];
The main ray casting procedure. Scene Ray must be in WORLD coordinates before this procedure is called.
RayCastNoBBoxes: PROC [sceneRay: Ray, node: REF ANY, makeStream: BOOLFALSE, f: IO.STREAMNIL, indent: NAT ← 0] RETURNS [class: Classification];
Like RayCast but ignore any bounding boxes which were computed. This is useful if the ray does not originate from the screen (as for computing shadows). Of course, bounding spheres would be useful in this case.
HitsTree: PROC [worldRay: Ray, tree: CSGTree] RETURNS [BOOL];
FirstHit: PROC [worldRay: Ray, tree: CSGTree, makeStream: BOOLFALSE, f: IO.STREAMNIL, indent: NAT ← 0] RETURNS [hits: BOOL, t: REAL];
Combine: PROC [leftClass, rightClass: Classification, op: PointSetOp] RETURNS [combinedClass: Classification];
SingleRay: PROC [x, y: INTEGER, tree: CSGTree, lightSources: LightSourceList, camera: Camera, makeStream: BOOLFALSE, f: IO.STREAMNIL] RETURNS [color: Color];
SingleRay2: PROC [cameraPoint: Point2d, tree: CSGTree, lightSources: LightSourceList, camera: Camera, makeStream: BOOLFALSE, f: IO.STREAMNIL] RETURNS [class: Classification];
The client must be sure to call ReturnClassToPool[class] when he is done with it.
SetScanSize: PROC [height, width: NAT];
DrawTree: PROC [dc: Graphics.Context, tree: CSGTree, lightSources: LightSourceList, camera: Camera, aisRope: Rope.ROPE, bAndWOnly: BOOL, notify: NotifyOfProgressProc ← NoOpNotifyOfProgress, clientData: REF ANYNIL, outStream: IO.STREAM] RETURNS [success: BOOL];
DrawTree calls notify once before starting each line (row) of pixels.
NotifyOfProgressProc: TYPE = PROC [currentY, minX, minY, maxX, maxY: REAL, clientData: REF ANYNIL];
NoOpNotifyOfProgress: NotifyOfProgressProc;
Text: TYPE = REF READONLY TEXT;
GetClassFromPool: PROC RETURNS [class: Classification];
ReturnClassToPool: PROC [class: Classification];
MakeClassAMiss: PROC [class: Classification];
Rearranges class to correspond to a complete miss.
GetRayFromPool: PROC RETURNS [ray: Ray];
ReturnRayToPool: PROC [ray: Ray];
END.