Render3dSceneImpl.mesa
Last Edited by: Crow, August 11, 1986 10:55:19 am PDT
DIRECTORY
Rope     USING [ Cat, ROPE, Substr, Index ],
Convert    USING [ RopeFromReal, RopeFromInt, TimeFromRope ],
BasicTime   USING [ GetClockPulses, PulsesToSeconds, Period, Now, GMT ],
IO      USING [ UnsafePutBlock ],
Terminal    USING [ Current ],
ColorDisplay   USING [ GetColorDisplayStatus, SetColorDisplayStatus ],
WindowManager USING [ StopColorViewers ],
Real     USING [ Fix, RoundI, Float ],
ComputeServerServer USING [ Register ],
Commander   USING [ CommandProc, Register ],
Args     USING [ Arg, ArgsGet ],
Pixels     USING [ GetScanSeg, GetFromTerminal, PixelBuffer, SampleSetSequence ],
SampleMapOps  USING [ GetPointer ],
ThreeDMisc   USING [ AddShapeAt, MakeFrameFromFile, MakeFrame,
         SetSmoothColor, SetFacetedColor ],
ThreeDScenes  USING [ Error, Create, ReadScene, SetEyeSpace,
         SetLight, SetView, SetViewPort, SetWindow,
         WindowFromViewPort ],
ThreeDBasics  USING [ Context ];
Render3dSceneImpl: CEDAR PROGRAM
IMPORTS Args, BasicTime, ColorDisplay, Commander, ComputeServerServer, Convert, IO, Pixels, Real, Rope, SampleMapOps, Terminal, ThreeDMisc, ThreeDScenes, WindowManager
~ BEGIN
Ceiling: PROC[ in: REAL ] RETURNS[ out: INTEGER ] ~ {
out ← Real.RoundI[in];
IF Real.Float[out] < in THEN out ← out + 1;
};
ElapsedTime: PROC[startTime: REAL] RETURNS[Rope.ROPE] ~ {
timeX100: REAL ← 100.0 * (BasicTime.PulsesToSeconds[BasicTime.GetClockPulses[]] - startTime);
RETURN[ Rope.Cat[ Convert.RopeFromReal[ Real.Fix[timeX100] / 100.0 ], " s. " ] ];
};
CurrentTime: PROC[] RETURNS[REAL] ~ {
RETURN[ BasicTime.PulsesToSeconds[BasicTime.GetClockPulses[]] ];
};
GetContext: PROC[] RETURNS[REF ThreeDBasics.Context] ~ {
context: REF ThreeDBasics.Context;
renderMode: ATOM;
display: Pixels.PixelBuffer;
on, onLeft, gray: BOOLEAN;
bpp, bppB: CARDINAL;
monitorType: Rope.ROPE;
[on, onLeft, gray, bpp, bppB, monitorType] ← ColorDisplay.GetColorDisplayStatus[];
IF on THEN WindowManager.StopColorViewers[]; -- get rid of conflicting users of color display
IF bpp < 8 THEN bpp ← 8;
ColorDisplay.SetColorDisplayStatus[
on: TRUE, onLeft: onLeft, gray: FALSE, bpp: bpp, monitorType: monitorType
];
display ← Pixels.GetFromTerminal[vt: Terminal.Current[], alpha: FALSE, depth: TRUE];
SELECT display.samplesPerPixel FROM
2 => renderMode ← $PseudoClr;
4 => renderMode ← $Dorado24;
ENDCASE => ThreeDScenes.Error[[$MisMatch, "Strange Error??"]];
context ← ThreeDScenes.Create[ width: 0, height: 0, renderMode: renderMode,
         
alpha: FALSE, depth: TRUE ];
context.display ← display;
ThreeDScenes.SetViewPort[context, [0.0, 0.0, context.display.width, context.display.height] ];
ThreeDScenes.SetWindow[context, ThreeDScenes.WindowFromViewPort[context.viewPort] ];
[] ← ThreeDScenes.SetLight[context, "Initial", [-100., -200., 50.] ];
ThreeDScenes.SetView[ context, [0.0, -10.0, 3.0], [0.0, 0.0, 0.0] ];
RETURN[context];
};
Render3dSceneProc: Commander.CommandProc ~ {
Renders scene described by file name on command line, displays on available display
context: REF ThreeDBasics.Context ← GetContext[ ! ThreeDScenes.Error => GO TO GiveUp ];
fileName: Rope.ROPE ← Rope.Substr[
base: cmd.commandLine,
start: 1,
len: Rope.Index[cmd.commandLine, 0, "\n"] - 1
];
ThreeDMisc.MakeFrameFromFile[context, fileName];
EXITS GiveUp => NULL
};
Render3dShapeProc: Commander.CommandProc ~ {
Renders shape described file name on command line, displays on available display
context: REF ThreeDBasics.Context ← GetContext[];
ok: BOOL;
shapeFile, x, y, z, fr, fg, fb, sr, sg, sb: Args.Arg;
[ok, shapeFile, x, y, z, fr, fg, fb, sr, sg, sb] ← Args.ArgsGet[cmd,
            "%s-from%rrr-faceted%rrr-smooth%rr"];
IF NOT ok THEN SIGNAL ThreeDScenes.Error[[$MisMatch, "command line bad"]];
IF NOT shapeFile.ok THEN SIGNAL ThreeDScenes.Error[[$MisMatch, "no shape to render"]];
IF x.ok AND y.ok AND z.ok
THEN ThreeDScenes.SetView[context, [x.real, y.real, z.real], [0.0, 0.0, 0.0] ];
ThreeDMisc.AddShapeAt[context, "Shape", shapeFile.rope, [0.,0.,0.]];
IF fr.ok AND fg.ok AND fb.ok
THEN ThreeDMisc.SetFacetedColor[ context, "Shape", [fr.real, fg.real, fb.real] ]
ELSE IF sr.ok AND sg.ok AND sb.ok
THEN ThreeDMisc.SetSmoothColor[ context, "Shape", [sr.real, sg.real, sb.real] ]
ELSE ThreeDMisc.SetSmoothColor[ context, "Shape", [1.0, 0.8, 0.2] ];
ThreeDMisc.MakeFrame[context];
};
RenderFromStreamProc: Commander.CommandProc ~ {
CommandProc: TYPE = PROC [cmd: Handle] RETURNS [result: REF ← NIL, msg: ROPE ← NIL];
Renders scene described on input stream, passes pixels back on output stream
startTime, lastTime: REAL ← CurrentTime[];
procTime: BasicTime.GMT ← BasicTime.Now[];
scanSeg: REF Pixels.SampleSetSequence;
displaycontext: REF ThreeDBasics.Context;
context: REF ThreeDBasics.Context ← ThreeDScenes.Create[ 0, 0, $FullClr, TRUE];
serverDelay: INT ← BasicTime.Period[ Convert.TimeFromRope[cmd.commandLine], procTime ];
IF serverDelay > 0 AND serverDelay < 3600
THEN msg ← Rope.Cat[" delay: ", Convert.RopeFromInt[ serverDelay], " s. " ];
ThreeDScenes.ReadScene[context, cmd.in];
displaycontext ← ThreeDScenes.Create[    -- get display bits of proper size
width: Ceiling[context.viewPort.w],
height: Ceiling[context.viewPort.h],
renderMode: $FullClr,
alpha: TRUE
];
context.display ← displaycontext.display;   -- give display bits to context
ThreeDScenes.SetEyeSpace[context];    -- update for actual display size
msg ← Rope.Cat[msg, " set-up: ", ElapsedTime[startTime] ]; lastTime ← CurrentTime[];
ThreeDMisc.MakeFrame[context];        -- render image
msg ← Rope.Cat[msg, " rendering: ", ElapsedTime[lastTime] ]; lastTime ← CurrentTime[];
Write pixels back on output stream
FOR y: NAT IN [0 .. Ceiling[context.viewPort.h] ) DO
scanSeg ← Pixels.GetScanSeg[context.display, 0, y, Ceiling[context.viewPort.w], scanSeg];
FOR i: NAT IN [0.. context.display.samplesPerPixel) DO
TRUSTED {
IO.UnsafePutBlock[ -- uses 16 bits per byte (wasting net bandwidth)
self: cmd.out,
block: [ base: LOOPHOLE[SampleMapOps.GetPointer[scanSeg[i], 0, scanSeg[i].length]],
  count: 2*scanSeg[i].length ]
];
};
ENDLOOP;
ENDLOOP;
msg ← Rope.Cat[msg, " output: ", ElapsedTime[lastTime], " total: ", ElapsedTime[startTime] ];
context ← displaycontext ← NIL;     -- kill off everything, no state saved  
};
Init: PROC ~ {
ComputeServerServer.Register[
key: "Render3dFromStream",
proc: RenderFromStreamProc
];
Commander.Register[
key: "RenderFromStream",
proc: RenderFromStreamProc
];
Commander.Register[
key: "Render3dScene",
proc: Render3dSceneProc
];
Commander.Register[
key: "Render3dShape",
proc: Render3dShapeProc
];
};
Init[];
END.