-- File: Preprocess3dImpl.mesa
-- Last edited by Bier on December 18, 1982 1:39 am
-- Author: Eric Bier on July 2, 1983 5:55 pm
-- Contents: File CSGImpl.mesa overflowed storage so I will put the preprocessing phases of ray casting in this interface. Preprocessing may include calculation transforms and their inverses, bounding boxes, unit rays in each instance coordinate system, and so forth.

DIRECTORY
 ColorMap,
 ColorPackagePrivate,
CSG,
 CSGGraphics,
 DisplayList3d,
 Map,
 Preprocess3d,
 Real,
 Rope,
 SVArtwork,
 SVBoundBox,
 SVVector3d;

Preprocess3dImpl: PROGRAM
IMPORTS ColorMap, ColorPackagePrivate, CSG, Map, SVArtwork, SVBoundBox
EXPORTS Preprocess3d =
BEGIN

BoundBox: TYPE = REF BoundBoxObj;
BoundBoxObj: TYPE = SVBoundBox.BoundBoxObj;
Camera: TYPE = CSGGraphics.Camera;
MasterObject: TYPE = DisplayList3d.MasterObject;
Vector: TYPE = SVVector3d.Vector;
LightSourceList: TYPE = DisplayList3d.LightSourceList;

Primitive: TYPE = REF PrimitiveObj;
PrimitiveObj: TYPE = CSG.PrimitiveObj;

SurfaceArray: TYPE = REF SurfaceArrayObj;
SurfaceArrayObj: TYPE = CSG.SurfaceArrayObj; -- ARRAY[1..maxSceneDepth] OF Surface;
Surface: TYPE = REF ANY;

PointSetOp: TYPE = CSG.PointSetOp; -- {union, intersection, difference};

Composite: TYPE = REF CompositeObj;
CompositeObj: TYPE = CSG.CompositeObj;

CSGTree: TYPE = REF CSGTreeObj;
CSGTreeObj: TYPE = CSG.CSGTreeObj;

Preprocess: PUBLIC PROC [tree: CSGTree, camera: Camera] RETURNS [bb: BoundBox] = {
IF tree.son = NIL THEN RETURN[ NIL ];
 OpenArtworksInNode[tree.son];
 bb ← FindBoundingBoxesInNode[tree.son, camera];
 };

OpenArtworksInNode: PRIVATE PROC [node: REF ANY] = {
-- tree walk through to the leaves and find the position of each primitive.
WITH node SELECT FROM
 comp: Composite => {OpenArtworksInNode[comp.leftSolid];
        OpenArtworksInNode[comp.rightSolid];};
 prim: Primitive => {
  SVArtwork.OpenArtwork[prim.artwork];
  RETURN;
  };
ENDCASE => ERROR;
 }; -- end of OpenArtworksInNode

FindBoundingBoxesInNode: PRIVATE PROC [node: REF ANY, camera: Camera] RETURNS [BoundBox] = {
-- tree walk find the bound box of each primitive and composite.
-- primWRTWorld and worldWRTPrim should be available. ie FindTransformsInNode must be done first.
WITH node SELECT FROM
 comp: Composite => {-- bounding box is the combination of the bounding boxes of the children.
   comp.boundBox ← CSG.CombineBoundBoxes[
    FindBoundingBoxesInNode[comp.leftSolid, camera],
    FindBoundingBoxesInNode[comp.rightSolid, camera],
    comp.operation];
   RETURN[comp.boundBox];
   };
 prim: Primitive => {-- bounding box is found from the bounding poly hedron
   mo: MasterObject;
   prim.boundBox ← SVBoundBox.BoundBoxFromBoundHedron[prim.boundHedron, camera, prim.primWRTAssembly];
   mo ← NARROW[prim.mo];
   mo.class.preprocess[prim, camera];
    RETURN[prim.boundBox];
   };
ENDCASE => ERROR;
 }; -- end of FindBoundingBoxesInNode

FindRayStepXInPrimitives: PUBLIC PROC [node: REF ANY] = {
-- do this before casting any rays so that we only have to do it once.
-- finds
WITH node SELECT FROM
 comp: Composite => {-- keep walking we only care about primitives
   FindRayStepXInPrimitives[comp.leftSolid];
   FindRayStepXInPrimitives[comp.rightSolid];
   };
 prim: Primitive => {-- here
   };
ENDCASE => ERROR;
 }; -- end of FindRayStepXInPrimitives

globalTable: Map.ColorTable;
globalPalette: Map.PalTable;

GetGlobalTable: PUBLIC PROC RETURNS [Map.ColorTable] = {
RETURN[globalTable];
 };

SetUpColorMap: PUBLIC PROC = {
 [globalTable, globalPalette] ← Map.Restore["Std.Tab"]; -- get the standard color map from this file
 ColorPackagePrivate.SetNewColorMapProc[PaletteMapper];
FOR palix: CARDINAL IN[0..globalPalette.size) DO
  ColorMap.SetRGBColor[palix,
   globalPalette[palix].r, globalPalette[palix].g, globalPalette[palix].b];
ENDLOOP;
 };

PaletteMapper: ColorPackagePrivate.ColorMapProc = TRUSTED {
RETURN[Map.GetIndex[r,g,b, globalTable]];
 };

Init: PROC = {
 };

Init[];

END.