G3dPatchCmdImpl.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Bloomenthal, October 21, 1992 6:43 pm PDT
DIRECTORY Commander, Controls, Draw2d, G3dBasic, G3dControl, G3dDraw, G3dMatrix, G3dPatch, G3dTool, G3dView, Real, ViewerOps;
G3dPatchCmdImpl: CEDAR PROGRAM
IMPORTS Controls, Draw2d, G3dControl, G3dDraw, G3dMatrix, G3dPatch, G3dTool, G3dView, Real, ViewerOps
~ BEGIN
IntegerPair:   TYPE ~ RECORD [i, j: INTEGER];
Data:     TYPE ~ REF DataRep;
DataRep:    TYPE ~ RECORD [
camera:      G3dControl.CameraControl ¬ NIL,
outer:       Controls.Viewer ¬ NIL,
outerData:     Controls.OuterData ¬ NIL,
graphics:      Controls.Viewer ¬ NIL,
view:       G3dMatrix.Matrix ¬ NIL,
hold:       G3dControl.Hold ¬ NIL,
res:       Controls.Control ¬ NIL,
selected:      IntegerPair ¬ [-1, -1],
patch:       G3dPatch.Patch ¬ NIL
];
PatchCmd: Commander.CommandProc ~ {
t13: REAL ¬ 1.0/3.0;
d: Data ~ NEW[DataRep];
cp: G3dPatch.ControlPoints ¬ NEW[G3dPatch.ControlPointsRep];
cp[0] ¬ [[-1.0, -1.0, 0.0], [-1.0/3.0, -1.0, 0.5], [1.0/3.0, -1.0, 0.5], [1.0, -1.0, 0.0]];
cp[1] ¬ [[-1.0, -t13, 0.0], [-1.0/3.0, -t13, 0.5], [1.0/3.0, -t13, 0.5], [1.0, -t13, 0.0]];
cp[2] ¬ [[-1.0, t13, 0.0], [-1.0/3.0, t13, 0.5], [1.0/3.0, t13, 0.5], [1.0, t13, 0.0]];
cp[3] ¬ [[-1.0, 1.0, 0.0], [-1.0/3.0, 1.0, 0.5], [1.0/3.0, 1.0, 0.5], [1.0, 1.0, 0.0]];
d.patch ¬ G3dPatch.FromBezier[cp];
d.camera ¬ G3dControl.InitCameraControl[proc: CameraControl, fieldOfView: 0, clientData: d];
d.hold ¬ G3dControl.InitHold[ControlPointMove, d];
d.res ¬ Controls.NewControl[name: "Res", min: 3, max: 20, init: 5, precision: 0, proc: Res];
d.outerData ¬ Controls.OuterViewer[
name: "Test Patch",
controls: LIST[
d.camera.fieldOfView, d.camera.scale,
d.camera.proxy.xRot, d.camera.proxy.yRot, d.camera.proxy.zRot,
d.hold.x, d.hold.y, d.hold.z, d.res],
typescriptHeight: 18,
graphicsHeight: 400,
mouseProc: Mouser,
drawProc: Drawer,
clientData: d
];
d.outer ¬ d.outerData.parent;
d.graphics ¬ d.outerData.graphics;
};
CameraControl: Controls.ControlProc ~ {
IF control.mouse.button = right AND control.mouse.state # up
THEN Repaint[NARROW[clientData]];
};
Drawer: Controls.DrawProc ~ {
d: Data ~ NARROW[clientData];
Action: PROC ~ {
res: NAT ¬ Real.Round[d.res.value];
vp: G3dMatrix.Viewport ¬ G3dView.GetViewport[viewer];
cp: G3dPatch.ControlPoints ¬ d.patch.controlPoints;
d.view ¬ G3dControl.InitContext[context, d.camera, viewer,, d.view];
IF d.selected # [-1, -1] THEN
G3dDraw.Mark[context, cp[d.selected.i][d.selected.j], d.view, vp,, asterisk];
G3dDraw.Patch[context, d.view, vp, d.patch, res, res];
FOR i: NAT IN [0..4) DO FOR j: NAT IN [0..3) DO
G3dDraw.Segment[context, cp[i][j], cp[i][j+1], d.view, vp, dotted];
G3dDraw.Segment[context, cp[j][i], cp[j+1][i], d.view, vp, dotted];
ENDLOOP; ENDLOOP;
};
Draw2d.DoWithBuffer[context, Action];
};
Mouser: Controls.MouseProc ~ {
d: Data ~ NARROW[clientData];
minSq: REAL ¬ 1000000.0;
FOR i: NAT IN [0..4) DO FOR j: NAT IN [0..4) DO
p: G3dBasic.Pair ¬ G3dMatrix.TransformD[d.patch.controlPoints[i][j], d.view];
dx: REAL ¬ mouse.pos.x-p.x;
dy: REAL ¬ mouse.pos.y-p.y;
sq: REAL ¬ dx*dx+dy*dy;
IF sq < minSq THEN {minSq ¬ sq; d.selected ¬ [i, j]};
ENDLOOP; ENDLOOP;
G3dControl.SetHold[d.hold, d.patch.controlPoints[d.selected.i][d.selected.j]];
Repaint[d];
};
Res: Controls.ControlProc ~ {Repaint[NARROW[control.clientData]]};
ControlPointMove: Controls.ControlProc ~ {
d: Data ~ NARROW[control.clientData];
d.patch.controlPoints[d.selected.i][d.selected.j] ¬ [d.hold.x.value, d.hold.y.value, d.hold.z.value];
d.patch ¬ G3dPatch.FromBezier[d.patch.controlPoints, d.patch];
Repaint[d];
};
Repaint: PROC [d: Data] ~ {ViewerOps.PaintViewer[d.graphics, client, FALSE, d]};
G3dTool.Register["Patch", PatchCmd, "play with patches"];
END.