IF context3d # NIL THEN {
normal: Triple;
window: Imager.Rectangle;
aspectRatio, viewWidth, viewHeight: REAL;
bounds: Pixels.Extent ← [0, 0, Ceiling[context3d.viewPort.w], Ceiling[context3d.viewPort.h]];
From ThreeDScenes.SetEyeSpace:
context3d.eyeSpaceXfm ← matrix;
IF bounds.h <= 0.0 OR bounds.w <= 0.0 THEN RETURN;
aspectRatio ← REAL[bounds.w]/REAL[bounds.h];
IF context3d.window.w < 0.0 OR context3d.window.h < 0.0 THEN RETURN;
IF context3d.fieldOfView = 0.0 THEN context3d.fieldOfView ← 40.0;
viewWidth ← 2.0*RealFns.TanDeg[0.5*context3d.fieldOfView];
window.x ← MIN[1.0, MAX[-1.0, context3d.window.x] ];
window.w ← MIN[1.0-window.x, context3d.window.w ];
window.y ← MIN[1.0, MAX[-1.0, context3d.window.y] ];
window.h ← MIN[1.0-window.y, context3d.window.h ];
context3d.clippingPlanes[Near] ← [0.0, 0.0, 1.0, -context3d.hitherLimit];
context3d.clippingPlanes[Far] ← [0.0, 0.0, -1.0, context3d.yonLimit];
normal ← Vector3d.Normalize[[1.0, 0.0, -0.5*window.x*viewWidth]];
context3d.clippingPlanes[Left] ← [normal.x, 0.0, normal.z, 0.0];
normal ← Vector3d.Normalize[[-1.0, 0.0, 0.5*(window.x + window.w)*viewWidth]];
context3d.clippingPlanes[Right] ← [normal.x, 0.0, normal.z, 0.0];
normal ← Vector3d.Normalize[[0.0, 1.0, -0.5*window.y*viewWidth]];
context3d.clippingPlanes[Bottom] ← [0.0, normal.y, normal.z, 0.0];
normal ← Vector3d.Normalize[[0.0, -1.0, 0.5*(window.y + window.h)*viewWidth]];
context3d.clippingPlanes[Top] ← [0.0, normal.y, normal.z, 0.0];
IF aspectRatio > 1.0
THEN {viewHeight ← viewWidth; viewWidth ← viewWidth*aspectRatio}
ELSE viewHeight ← viewWidth/aspectRatio;
IF window.w > window.h
THEN viewWidth ← viewWidth*window.h/window.w
ELSE viewHeight ← viewHeight*window.w/window.h;
context3d.eyeToNDC.addX ← -window.x/window.w;
context3d.eyeToNDC.addY ← -window.y/window.h;
context3d.eyeToNDC.addZ ← 1.0/(1.0-context3d.hitherLimit/context3d.yonLimit);
context3d.eyeToNDC.scaleX ← 1.0/(0.5*window.w*viewWidth);
context3d.eyeToNDC.scaleY ← 1.0/(0.5*window.h*viewHeight);
context3d.eyeToNDC.scaleZ ←
-context3d.hitherLimit/(1.0-context3d.hitherLimit/context3d.yonLimit);
From ThreeDScenesImpl.SetView:
FOR n: NAT IN [0..context3d.shapes.length) DO
shape: REF ShapeInstance ← context3d.shapes[n];
shape.vtcesInValid ← TRUE;
IF ThreeDScenes.GetShading[shape, $Shininess] # NIL
THEN shape.shadingInValid ← TRUE;
ENDLOOP;
};