G3dSceneImpl.mesa
Copyright © 1988 by Xerox Corporation. All rights reserved.
Bloomenthal, March 12, 1989 9:03:00 pm PST
DIRECTORY Ascii, Atom, Commander, CommandTool, FileNames, FS, G3dBasic, G3dRender, G3dShape, G3dScene, G3dVector, IO, MessageWindow, Rope, RopeFile, TiogaAccess, TiogaMenuOps, TiogaOps, ViewerOps, ViewerTools;
G3dSceneImpl:
CEDAR
PROGRAM
IMPORTS Atom, CommandTool, FileNames, FS, G3dRender, G3dShape, G3dVector, IO, MessageWindow, Rope, RopeFile, TiogaAccess, TiogaMenuOps, TiogaOps, ViewerOps, ViewerTools
EXPORTS G3dScene
Type Declarations
Pair: TYPE ~ G3dBasic.Pair;
Triple: TYPE ~ G3dBasic.Triple;
RGB: TYPE ~ G3dRender.RGB;
Context: TYPE ~ G3dRender.Context;
RenderData: TYPE ~ G3dRender.RenderData;
RenderStyle: TYPE ~ G3dRender.RenderStyle;
TextureStyle: TYPE ~ G3dRender.TextureStyle;
TextureInfo: TYPE ~ G3dRender.TextureInfo;
LogProc: TYPE ~ G3dScene.LogProc;
ViewerSelection: TYPE ~ G3dScene.ViewerSelection;
Shape: TYPE ~ G3dShape.Shape;
STREAM: TYPE ~ IO.STREAM;
ROPE: TYPE ~ Rope.ROPE;
Writer: TYPE ~ TiogaAccess.Writer;
SelPos: TYPE ~ ViewerTools.SelPos;
Viewer: TYPE ~ ViewerTools.Viewer;
Write Scene Descriptions to a Viewer
Item:
TYPE ~
RECORD [name:
ROPE, value:
REAL];
WriteInfo:
TYPE ~
RECORD [
writer: Writer ← NIL,
fileName: ROPE ← NIL,
stream: STREAM ← NIL,
ok: BOOL ← TRUE];
GetWriteInfo:
PROC
RETURNS [i: WriteInfo] ~ {
v: Viewer ← ViewerTools.GetSelectedViewer[];
i.writer ← TiogaAccess.Create[];
IF Rope.Length[ViewerTools.GetSelectionContents[]] # 0
THEN i.fileName ← FileNames.ResolveRelativePath[ViewerTools.GetSelectionContents[]]
ELSE i.ok ← v # NIL AND (v.class.flavor = $Text OR v.class.flavor = $Typescript);
IF NOT i.ok THEN Blink["Make primary selection"];
};
PutWriter:
PROC [i: WriteInfo] ~ {
WriteToViewer:
PROC [root: TiogaOps.Ref] ~ {
TiogaAccess.WriteSelection[i.writer ! TiogaAccess.Error => {Blink[expl]; CONTINUE}];
};
SELECT
TRUE
FROM
i.stream #
NIL =>
TiogaAccess.WriteOpenFile[i.writer,
FS.OpenFileFromStream[i.stream]
! FS.Error => {Blink[error.explanation]; CONTINUE}];
i.fileName #
NIL =>
TiogaAccess.WriteFile[i.writer, i.fileName
! FS.Error => {Blink[error.explanation]; CONTINUE}]
ENDCASE => TiogaOps.CallWithLocks[WriteToViewer];
};
Nest: PROC [w: Writer] ~ {TiogaAccess.Nest[w, 1]};
UnNest:
PROC [w: Writer] ~ {TiogaAccess.Nest[w, -1]};
WriteNode:
PROC [w: Writer, rope:
ROPE, looks:
ROPE ←
NIL] ~ {
tc: TiogaAccess.TiogaChar ← [charSet: 0, char: '\000, looks: ALL[FALSE], format: NIL, comment: FALSE, endOfNode: FALSE, deltaLevel: 0, propList: NIL];
FOR n:
INT
IN [0..Rope.Length[looks])
DO
c: CHAR ← Rope.Fetch[looks, n];
IF c IN TiogaAccess.Look THEN tc.looks[c] ← TRUE;
ENDLOOP;
FOR n:
INT
IN [0..Rope.Length[rope])
DO
tc.char ← Rope.Fetch[rope, n];
TiogaAccess.Put[w, tc];
ENDLOOP;
tc.endOfNode ← TRUE;
TiogaAccess.Put[w, tc];
};
WriteItem:
PROC [w: Writer, item: Item] ~ {WriteReal[w, item.name, item.value]};
WriteBool:
PROC [w: Writer, name:
ROPE, bool:
BOOL] ~ {
WriteNode[w, Rope.Cat[name, ":\t", IF bool THEN "True" ELSE "False"]];
};
WriteReal:
PROC [w: Writer, name:
ROPE, value:
REAL] ~ {
WriteNode[w, IO.PutFR["%g:\t%g", IO.rope[name], IO.real[value]]];
};
WritePair:
PROC [w: Writer, name:
ROPE, p: Pair] ~ {
WriteNode[w, IO.PutFR["%g:\t%g, %g", IO.rope[name], IO.real[p.x], IO.real[p.y]]];
};
WriteTriple:
PROC [w: Writer, name:
ROPE, t: Triple] ~ {
WriteNode[w,
IO.PutFR["%g:\t(%g,
%g,
%g)",
IO.rope[name], IO.real[t.x], IO.real[t.y], IO.real[t.z]]];
};
WriteRGB:
PROC [w: Writer, name:
ROPE, rgb: RGB] ~ {
WriteTriple[w, name, [rgb.R, rgb.G, rgb.B]];
};
WriteFour:
PROC [w: Writer, name:
ROPE, v1, v2, v3, v4:
REAL] ~ {
WriteNode[w,
IO.PutFR["%g:\t(%g,
%g,
%g, %g)",
IO.rope[name], IO.real[v1], IO.real[v2], IO.real[v3], IO.real[v4]]];
};
WriteTitle:
PROC [w: Writer, title:
ROPE] ~ {
WriteNode[w, title, "b"];
Nest[w];
};
WriteBlock:
PROC [w: Writer, title:
ROPE, items:
LIST
OF Item] ~ {
WriteTitle[w, title];
FOR l: LIST OF Item ← items, l.rest WHILE l # NIL DO WriteItem[w, l.first]; ENDLOOP;
UnNest[w];
};
WriteShape:
PROC [w: Writer, s: Shape] ~ {
shade: REF G3dRender.ShadingClass ← G3dRender.ShadingClassFromShape[s];
WriteTitle[w, Rope.Cat["ShapeRead ", s.name]];
WriteBool[w, "ShapeBackFaces", s.showBackfaces];
WriteNode[w, Rope.Cat["ShapeRenderStyle: ", Atom.GetPName[shade.type]]];
WriteRGB[w, "ShapeColor", shade.color];
WriteReal[w, "ShapeShininess", shade.shininess];
IF shade.transmittance # 0.0 THEN WriteReal[w, "ShapeTransmittance", shade.transmittance];
WriteTriple[w, "ShapePosition", s.position];
WritePair[w, "ShapeTextureScale", shade.textureScale];
WriteReal[w, "ShapeBumpScale", shade.bumpScale];
FOR l:
LIST
OF TextureInfo ← G3dRender.GetTextureInfo[s], l.rest
WHILE l #
NIL
DO
WriteNode[w,
IO.PutFR["Shape%gMap %g, ShapeTextureFiltering: ",
IO.rope[G3dRender.RopeFromTextureStyle[l.first.type]],
IO.rope[l.first.name],
IO.rope[IF l.first.filtered THEN "True" ELSE "False"]]];
ENDLOOP;
UnNest[w];
};
WriteLight:
PROC [w: Writer, s: Shape] ~ {
shade: REF G3dRender.ShadingClass ← G3dRender.ShadingClassFromShape[s];
WriteNode[w,
IO.PutFLR["%g: %g, (%g, %g, %g), (%g, %g, %g)",
LIST[
IO.rope["LightAdd"],
IO.rope[s.name],
IO.real[s.position.x], IO.real[s.position.y], IO.real[s.position.z],
IO.real[shade.color.R], IO.real[shade.color.G], IO.real[shade.color.B]]]];
};
WriteCamera:
PROC [context: Context, w: Writer] ~ {
WriteTitle[w, "Camera Parameters"];
WriteReal[w, "CameraFieldOfView", context.fieldOfView];
WriteTriple[w, "CameraEyePoint", context.eyePoint];
WriteTriple[w, "CameraLookAt", context.lookAt];
WriteTriple[w, "CameraUp", context.upDirection];
WriteReal[w, "CameraRoll", context.rollAngle];
UnNest[w];
};
WriteCameraParameters:
PUBLIC PROC [context: Context] ~ {
i: WriteInfo ← GetWriteInfo[];
IF NOT i.ok THEN RETURN;
WriteCamera[context, i.writer];
WriteNode[i.writer, NIL];
UnNest[i.writer];
PutWriter[i];
};
WriteParameters:
PUBLIC
PROC [context: Context, fileName:
ROPE ←
NIL] ~ {
i: WriteInfo ← IF fileName = NIL THEN GetWriteInfo[] ELSE [TiogaAccess.Create[], fileName];
WriteParametersToWriter[context, i];
};
WriteParametersToStream:
PUBLIC
PROC [context: Context, out:
STREAM] ~ {
WriteParametersToWriter[context, [writer: TiogaAccess.Create[], stream: out]];
};
WriteParametersToWriter:
PUBLIC PROC [c: Context, i: WriteInfo] ~ {
w: Writer ← i.writer;
IF NOT i.ok OR c = NIL THEN RETURN;
WriteNode[w, "3d Context Parameters", "bz"];
Nest[w];
WriteCamera[c, w];
WriteTitle[w, "Image Parameters"];
WriteNode[w, Rope.Cat["DisplayMode: ",
G3dRender.RopeFromDisplayMode[G3dRender.GetDisplayMode[c]]]];
IF c.window #
NIL
THEN WriteFour[w, "DisplayRegion", c.window.x, c.window.y, c.window.w, c.window.h];
IF c.preferredViewPort # [0.0, 0.0, 65536.0, 65536.0]
THEN WriteFour[w, "Viewport: ",
c.preferredViewPort.x, c.preferredViewPort.y,
c.preferredViewPort.w, c.preferredViewPort.h];
WriteRGB[w, "Background", G3dRender.GetBackgroundColor[c]];
IF G3dRender.GetBackgroundImage[c] #
NIL
THEN WriteNode[w, Rope.Cat["BackgroundImage", G3dRender.GetBackgroundImage[c]]];
WriteBool[w, "AntiAliasing", c.antiAliasing];
UnNest[w];
WriteTitle[w, "Lights"];
FOR n:
NAT
IN [0..c.shapes.length)
DO
IF G3dRender.ShadingClassFromShape[c.shapes[n]].type = $Light
THEN WriteLight[w, c.shapes[n]];
ENDLOOP;
WriteTitle[w, "Shapes"];
FOR n:
NAT
IN [0..c.shapes.length)
DO
IF G3dRender.ShadingClassFromShape[c.shapes[n]].type # $Light
THEN WriteShape[w, c.shapes[n]];
ENDLOOP;
WriteRGB[w, "LightAmbience", G3dRender.GetAmbientLight[c]];
UnNest[w];
WriteNode[w, NIL];
UnNest[w];
UnNest[w];
PutWriter[i];
};
Read Scene Descriptions from a Viewer or a File
ReadInfo:
TYPE ~
RECORD [operations:
ROPE,
v: Viewer, sel: SelPos, fileName:
ROPE ←
NIL];
GetReaderInfo:
PROC
RETURNS [i: ReadInfo] ~ {
i.operations ← ViewerTools.GetSelectionContents[];
IF Rope.Length[i.operations] = 0 THEN RETURN[[NIL, NIL, NIL]];
IF Rope.Length[i.operations] < 100
THEN {
i.fileName ← FileNames.ResolveRelativePath[i.operations];
i.fileName
←
FS.FileInfo[i
.fileName
! FS.Error => {i.fileName ← NIL; CONTINUE}].fullFName;
IF i.fileName # NIL THEN i.operations ← RopeFile.Create[i.fileName];
}
ELSE i.sel ← ViewerTools.GetSelection[i.v ← ViewerTools.GetSelectedViewer[]];
};
MakeFrameFromFile:
PUBLIC
PROC [context: Context, fileName:
ROPE] ~ {
GetPut:
PROC [a:
ATOM] ~ {
temp.props ← Atom.PutPropOnList[temp.props, a, Atom.GetPropFromList[context.props, a]];
};
temp: Context ← G3dRender.Create[];
temp.pixels ← context.pixels;
temp.viewer ← context.viewer;
temp.terminal ← context.terminal;
temp.class ← context.class;
temp.antiAliasing ← context.antiAliasing;
GetPut[$WDir];
GetPut[$Log];
[] ← ReadParameters[temp, fileName];
temp.class.render[temp];
temp ← NIL;
};
ReadParameters:
PUBLIC
PROC [context:
Context,
fileName:
ROPE
←
NIL, cmdOut:
STREAM ←
NIL]
RETURNS [shouldRepaint: BOOL] ~ {
i: ReadInfo ←
IF fileName =
NIL
THEN GetReaderInfo[]
ELSE [RopeFile.Create[fileName], NIL, NIL, fileName];
RETURN[Parse[context, i.operations, cmdOut,,
TRUE, i.fileName, [i.v, i.sel]
! ParseError => CONTINUE]];
};
Blink:
PROC [r:
ROPE] ~ {
MessageWindow.Append[Rope.Concat["\t\t", r], TRUE];
MessageWindow.Blink[];
};