perm filename VIEWER[GEM,BGB] blob sn#092032 filedate 1974-03-14 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00018 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	TITLE VIEWER  -  IMAGE FORMING SUBROUTINES  -  JULY 1972.
C00005 00003	SUBR(IIIDPY,WINDOW,GLASS)	DEVICE DEPENDENT DISPLAY ROUTINE.
C00007 00004	SUBR(SHOW1,WND,POG)		DISPLAY ALL EDGES IN VIEW.
C00011 00005	SUBR(SHOW4,WND,POG)	 	SHADOW HIDDEN LINE ELIMATION.
C00014 00006	SUBN(PPROJ,CAMERA,WORLD)
C00017 00007	SUBR(VPROJ,VERTEX,CAMERA)	VERTEX PERSPECTIVE PROJECTION.
C00019 00008	SUBR(UNPROJECT,VERTEX,CAMERA)
C00021 00009	SUBR(FACOEF,BF)		FACE COEFFICIENTS. BF>0 WC, BF<0 PP.
C00024 00010	 ENORM & VNORM
C00026 00011	SUBN(ZCLIPF,FACE,CAMERA)
C00028 00012	SUBN(FMRK,WORLD)		MARK POTENT FACES.
C00031 00013	SUBN(EMRK,WORLD)		MARK POTENT EDGES FOR OCCULT.
C00034 00014	SUBN(ZCLIP,VERT1,VERTU,VERT2,CAMERA)
C00037 00015	SUBN(XYCLIP)
C00039 00016	XY-CLIPPER continued.
C00041 00017	SUBR(CLIPER,WINDOW)
C00043 00018	XCLIP:		CLIP BODY RING.
C00047 ENDMK
C⊗;
TITLE VIEWER  -  IMAGE FORMING SUBROUTINES  -  JULY 1972.

	EXTERN OTHER,VCW,VCCW,ECCW
	EXTERN KLJUTS,KLJOTS,KLTMPS
	EXTERN UNIVERSE,DPYFLG,PLTFLG

;VARIABLES GLOBAL TO VIEWER SUBROUTINES.
	DECLARE{XL,XH,YL,YH}
	DECLARE{SOX,SOY,MAG}
	DECLARE{CAMERA,WINDOW,WORLD,GLASS}
	DECLARE{ALLSHARP}

SUBR(GEODPY)		;GEOMED'S DISPLAY REFRESH
COMMENT .-----------------------------------------------------------.
	MOVEI 1↔DAC GLASS
	LAC 1,UNIVERSE
	CW  1,1↔DAC 1,W0	;FIRST WINDOW OF DISPLAY RING.
L1:	DAC 1,W
	PUSH P,1↔PUSH P,GLASS

	LAC 1,DPYFLG
	SETZM DMODE↑↔CAIN 1,3↔SETOM DMODE	;OCCULT DIAGONOSTICS.

	PUSHJ P,@[SHOW2↔SHOW3↔SHOW1↔SHOW2](1)
	AOS 1,GLASS↔CAML 1,MAXGLASS↔DAC 1,MAXGLASS

L2:	LAC 1,W↔SIS 1,1		;NEXT WINDOW OF THE NOW DISPLAY RING.
	CAME 1,W0↔GO L1
	SETZB 0,1↔LAC 2,GLASS

L3:	CAML 2,MAXGLASS↔POP0J	;CLEAR HIGHER PIECES OF GLASS.
	DPB 2,[POINT 4,.+1,12]
	UPGIOT↔AOJA 2,L3
	DECLARE{W,W0,MAXGLASS,GLASS}

ENDR GEODPY;7/12/73(BGB)---------------------------------------------
SUBR(IIIDPY,WINDOW,GLASS)	;DEVICE DEPENDENT DISPLAY ROUTINE.
COMMENT .-----------------------------------------------------------.
	E←←16				;KEEP E OUT OF III AC'S.
	CALL(DPYSET↑,DPYBUF↑)		;NEW POG.

;DISPLAY WINDOW FRAME.
	LAC 1,WINDOW
	HLRE 1(1)↔DAC XL		;PICK UP 2D CLIPPER WINDOW.
	HRRE 1(1)↔DAC XH
	HLRE 2(1)↔DAC YL
	HRRE 2(1)↔DAC YH

	TESTZ 1,DARKEN↔GO L0
	CALL(AIVECT,XL,YL)		;MAKE A BOARDER.
	CALL(AVECT,XH,YL)
	CALL(AVECT,XH,YH)
	CALL(AVECT,XL,YH)
	CALL(AVECT,XL,YL)

;DISPLAY THE VISIBLE EDGE LIST.
L0:	LAC E,WINDOW
	NCAMR E,E↔PWRLD E,E↔JUMPE E,L3		;GET THE WORLD.
	PED E,E↔SKIPA				;1ST EDGE OF WORLD.
L1:	ALT2 E,E↔JUMPE E,L3			;CDR EDGE.
	X1DC 1,E↔Y1DC 2,E↔CALL(AIVECT↑,1,2)
	X2DC 1,E↔Y2DC 2,E↔CALL(AVECT↑,1,2)
	GO L1
L3:	CALL(DPYOUT↑,GLASS)
	POP2J
BEND IIIDPY;2/5/73(BGB)-------------------------------------------
SUBR(SHOW1,WND,POG)		;DISPLAY ALL EDGES IN VIEW.
COMMENT .-----------------------------------------------------------.
;ZERO WINDOW ARGUMENT PICKS UP THE DEFAULT WINDOW.
	SKIPN 2,UNIVERSE↔POP2J↔SETOM ALLSHARP
	SKIPN 1,WND↔CW 1,2↔DAC 1,WINDOW
	NCAMR 1,1↔DAC 1,CAMERA↔JUMPE 1,POP2J.
	PWRLD 1,1↔DAC 1,WORLD ↔JUMPE 1,POP2J.
	CALL(PPROJ,CAMERA,WORLD)
	CALL(CLIPER,WINDOW)
	CALL(IIIDPY,WINDOW,POG)↔POP2J
ENDR SHOW1;3/16/73(BGB)----------------------------------------------

SUBR(SHOW2,WND,POG)	 	;VECTOR HIDDEN LINE IMAGE.
COMMENT .-----------------------------------------------------------.
;ZERO WINDOW ARGUMENT PICKS UP THE DEFAULT WINDOW.
;ON NEGATIVE POG, DO NOT KILL TMPS.
	SKIPN 2,UNIVERSE↔POP2J↔SETZM ALLSHARP
	SKIPN 1,WND↔CW 1,2↔DAC 1,WINDOW
	NCAMR 1,1↔DAC 1,CAMERA↔JUMPE 1,POP2J.
	PWRLD 1,1↔DAC 1,WORLD ↔JUMPE 1,POP2J.
	TESTZ 1,DARKEN↔POP2J
	CALL(PPROJ,CAMERA,WORLD)
	CALL(FMRK,WORLD)
	CALL(EMRK,WORLD)
	CALL(OCCULT↑,WORLD)
	CALL(KLJOTS,WORLD)
	CALL(CLIPER,WINDOW)
	CALL(IIIDPY,WINDOW,POG)
	SKIPGE POG↔POP2J
	CALL(KLTMPS,WORLD)↔POP2J
ENDR SHOW2;3/16/73(BGB)----------------------------------------------

SUBR(SHOW3,WND,POG)	 	;DISPLAY BACKSIDED FACES REMOVED.
COMMENT .-----------------------------------------------------------.
;ZERO WINDOW ARGUMENT PICKS UP THE DEFAULT WINDOW.
	SKIPN 2,UNIVERSE↔POP2J↔SETZM ALLSHARP
	SKIPN 1,WND↔CW 1,2↔DAC 1,WINDOW
	NCAMR 1,1↔DAC 1,CAMERA↔JUMPE 1,POP2J.
	PWRLD 1,1↔DAC 1,WORLD ↔JUMPE 1,POP2J.
	CALL(PPROJ,CAMERA,WORLD)
	CALL(FMRK,WORLD)
	CALL(EMRK,WORLD)
	CALL(CLIPER,WINDOW)
	CALL(IIIDPY,WINDOW,POG)
	CALL(KLTMPS,WORLD)↔POP2J
ENDR SHOW3;3/16/73(BGB)----------------------------------------------
SUBR(SHOW4,WND,POG)	 	;SHADOW HIDDEN LINE ELIMATION.
COMMENT .-----------------------------------------------------------.
;ZERO WINDOW ARGUMENT PICKS UP THE DEFAULT WINDOW.
;ON NEGATIVE POG, DO NOT KILL TMPS.

	SKIPN 2,UNIVERSE↔POP2J↔SETZM ALLSHARP
	SKIPN 1,WND↔CW 1,2↔DAC 1,WINDOW
	NCAMR 1,1↔DAC 1,CAMERA↔JUMPE 1,POP2J.
	PWRLD 1,1↔DAC 1,WORLD ↔JUMPE 1,POP2J.
	ALT 1,1↔DAC 1,SUN#↔JUMPE 1,POP2J.

	CALL(PPROJ,SUN,WORLD)			;SUN SHINE PASS.
	CALL(FMRK,WORLD)
	CALL(EMRK,WORLD)
	CALL(OCCULT↑,WORLD)
	CALL(SHADOW↑,WORLD)

	CALL(PPROJ,CAMERA,WORLD)		;CAMERA PASS.
	CALL(FMRK,WORLD)
	CALL(EMRK,WORLD)
	CALL(OCCULT↑,WORLD)

	CALL(KLJOTS,WORLD)
	CALL(CLIPER,WINDOW)
	CALL(IIIDPY,WINDOW,POG)

	SKIPGE POG↔POP2J
	CALL(KLTMPS,WORLD)↔POP2J
ENDR SHOW4;3/11/74(BGB)----------------------------------------------

SUBR(TAKE1,CAMERA)			;SIMULATED PICTURE TAKE.
COMMENT .-----------------------------------------------------------.
	LAC 2,UNIVERSE↔PWRLD 2,2
	SKIPN 1,CAMERA↔NCAMR 1,2	;CAMERA ARGUMENT OR NOW CAMERA.
	DAC 1,CAMERA↔PWRLD 1,1↔DAC 1,WORLD
	CALL(PPROJ,CAMERA,WORLD)
	CALL(FMRK,WORLD)
	CALL(EMRK,WORLD)
	CALL(OCCULT↑,WORLD)
	CALL(OCCIMG↑)↔POP1J		;MAKE AN OCCULT IMAGE.
ENDR TAKE1;3/11/74(BGB)----------------------------------------------

SUBR(TAKE2,CAMERA)			;SIMULATED PICTURE TAKE.
COMMENT .-----------------------------------------------------------.
	LAC 2,UNIVERSE↔PWRLD 2,2
	SKIPN 1,CAMERA↔NCAMR 1,2	;CAMERA ARGUMENT OR NOW CAMERA.
	DAC 1,CAMERA↔PWRLD 1,1↔DAC 1,WORLD
	CALL(SHINE↑,WORLD)
	CALL(PPROJ,CAMERA,WORLD)
	CALL(FMRK,WORLD)
	CALL(EMRK,WORLD)
	CALL(OCCULT↑,WORLD)
	POP1J
ENDR TAKE2;3/11/74(BGB)----------------------------------------------
SUBN(PPROJ,CAMERA,WORLD)
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS{B,F,E,V,CAM,E0,X,XX,Y,YY,Z,ZZ}
	LAC B,WORLD↔$TYPE 0,B↔CAIE 0,$WORLD↔POP2J
;CLEAR FACE PZZ & NZZ BITS.
	LAC B,WORLD
I0:	CCW B,B↔CAME B,WORLD↔GO[LAC F,B
I1:	PFACE F,F↔CAMN F,B↔GO I0↔MARKZ F,PZZ+NZZ↔GO I1]

;GET THE CAMERA'S FRAME.
	LAC CAM,CAMERA
	LAC 3(CAM)↔DAC FOCL#		;FOCAL PLANE DISTANCE.
	FRAME CAM,CAM

;FOR ALL THE BODIES OF THE WORLD.
	LAC B,WORLD
L1:	CCW B,B↔CAMN B,WORLD↔POP2J
	MARKZ B,VISIBLE

;FOR ALL THE VERTICES OF EACH BODY.
	LAC V,B
L2:	PVT V,V↔CAMN V,B↔GO L1
	CALL(VPROJ,V,CAMERA)
;DO Z-CLIP MARKING WRT CAMERA CENTERED COORDINATES.
	LAC 0,[JUTBIT+JOTBIT+PZZ+NZZ+FOLDED+VISIBLE+POTENT+7B20]
	ANDCAM 0,(V)		;TURN 'EM ALL OFF.
	MOVSI X,(PZZ)		; + HALFSPACE, BEHIND THE CAMERA.
	MOVN FOCL
	CAMGE ZZ,0		;SKIP WHEN Zcc ≥ -FOCAL.
	MOVSI X,(NZZ)		; - HALFSPACE, INVIEW.
	IORM X,(V)

	PED E,V↔DAC E,E0↔JUMPE E,[
	PFACE F,B↔IORM X,(F)↔GO L1] 		;VERTEX BODY CASE.

L3:	PVT 1,E↔CAME 1,V↔GO .+3↔PCW 1,E↔GO L4	   ;AC1 ← ECCW(E,V).
	NVT 1,E↔CAME 1,V↔GO L2 ↔NCW 1,E
L4:	IORM X,(E)
	PFACE F,E↔IORM X,(F)
	NFACE F,E↔IORM X,(F)
	LAC E,1↔CAME E,E0↔GO L3↔GO L2
ENDR PPROJ;1/14/73(BGB)----------------------------------------------
SUBR(VPROJ,VERTEX,CAMERA)	;VERTEX PERSPECTIVE PROJECTION.
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS{B,F,E,V,CAM,E0,X,XX,Y,YY,Z,ZZ,FRM}

;PICKUP ARGUMENTS.
	LAC CAM,CAMERA
	FRAME FRM,CAM
	LAC V,VERTEX

;TRANSLATE VERTEX TO CAMERA LOCUS.
	LAC X,XWC(V)↔FSBR X,XWC(FRM)
	LAC Y,YWC(V)↔FSBR Y,YWC(FRM)
	LAC Z,ZWC(V)↔FSBR Z,ZWC(FRM)

;ROTATE TO CAMERA ORIENTATION.
	LAC XX,X↔FMPR XX,IX(FRM)
	LAC    Y↔FMPR    IY(FRM)↔FADR XX,
	LAC    Z↔FMPR    IZ(FRM)↔FADR XX,

	LAC YY,X↔FMPR YY,JX(FRM)
	LAC    Y↔FMPR    JY(FRM)↔FADR YY,
	LAC    Z↔FMPR    JZ(FRM)↔FADR YY,

	LAC ZZ,X↔FMPR ZZ,KX(FRM)
	LAC    Y↔FMPR    KY(FRM)↔FADR ZZ,
	LAC    Z↔FMPR    KZ(FRM)↔FADR ZZ,

;PERSPECTIVE TRANSFORMATION.
;XPP(V) ← SCALEX * XCC/ZCC.	SCALEX = -FOCAL/PDX.
;YPP(V) ← SCALEY * YCC/ZCC.	SCALEY = -FOCAL/PDY.
;ZPP(V) ← SCALEZ      /ZCC.	SCALEZ = -FOCAL/PDZ.
;ZPP(V) IS POSITIVE WHEN VERTEX IS INVIEW.   ←←← NOTA BENE.

	MOVM ZZ↔CAMGE[1E-7]↔LAC ZZ,[1E-7]	;AVOID ZERO DIVIDE.
	FMPR XX,-3(CAM)↔FDVR XX,ZZ↔DAC XX,XPP(V)
	FMPR YY,-2(CAM)↔FDVR YY,ZZ↔DAC YY,YPP(V)
	LAC   Z,-1(CAM)↔FDVR  Z,ZZ↔DAC  Z,ZPP(V)

	POP2J

ENDR VPROJ;(BGB)-----------------------------------------------------
SUBR(UNPROJECT,VERTEX,CAMERA)
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS{V,C,R,X,Y,Z,XX,YY,ZZ}

;PICKUP ARGUMENTS.
	LAC V,VERTEX
	LAC C,CAMERA
	FRAME R,C

;UNDO PERSPECTIVE.
	LAC  Z,-1(C)↔FDVR Z,ZPP(V)		;SCALEZ.
	LAC  Y,YPP(V)↔FMPR Y,Z↔FDVR Y,-2(C)	;SCALEY.
	LAC  X,XPP(V)↔FMPR X,Z↔FDVR X,-3(C)	;SCALEX.

;ROTATE BY TRANSPOSE OF CAMERA ORIENTATION.
	LAC XX,X↔FMPR XX,IX(R)
	LAC    Y↔FMPR    JX(R)↔FADR XX,
	LAC    Z↔FMPR    KX(R)↔FADR XX,

	LAC YY,X↔FMPR YY,IY(R)
	LAC    Y↔FMPR    JY(R)↔FADR YY,
	LAC    Z↔FMPR    KY(R)↔FADR YY,

	LAC ZZ,X↔FMPR ZZ,IZ(R)
	LAC    Y↔FMPR    JZ(R)↔FADR ZZ,
	LAC    Z↔FMPR    KZ(R)↔FADR ZZ,

;TRANSLATE TO CAMERA LOCUS.
	FADR XX,XWC(R)↔DAC XX,XWC(V)
	FADR YY,YWC(R)↔DAC YY,YWC(V)
	FADR ZZ,ZWC(R)↔DAC ZZ,ZWC(V)
	POP2J

ENDR UNPROJECT;1/14/73(BGB)------------------------------------------
SUBR(FACOEF,BF)		;FACE COEFFICIENTS. BF>0 WC, BF<0 PP.
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS {Q2,Q3,E,V1,V2,V3,ABC,F,ARG,E0}
	FOR @% Qε{XYZ}{FOR @$ N←1,3{		;DEFINE X1,Y1,Z1...
	DEFINE Q%$N<Q%WC(V$N)>↔}}
;FOR ALL THE FACES OF EACH BODY.
	MOVM F,BF↔LAC ARG,(F) 			;ORIGINAL ARG TYPE.
	TLNN ARG,(BBIT)↔GO L2
L1:	PFACE F,F↔TEST F,FBIT↔POP1J

;FIRST THREE VERTICES CCW ABOUT THE FACE.
L2:	PED E,F↔DAC E,E0
L3:	SETQ(V1,{VCW,E,F})
	SETQ(V2,{VCCW,E,F})
	SETQ(E,{ECCW,E,F})
	SETQ(V3,{VCCW,E,F})

;FLG TRUE FOR PERSPECTIVE PROJECTED FACOEF.
	SKIPG BF↔GO[ADDI V1,7↔ADDI V2,7↔ADDI V3,7↔GO .+1]

;KK(F) ← X1*(Z2*Y3-Y2*Z3) + Y1*(X2*Z3-Z2*X3) + Z1*(Y2*X3-X2*Y3).
	LAC 1,Z2↔FMPR 1,Y3↔LAC Y2↔FMPR Z3↔FSBR 1,0↔FMPR 1,X1↔LAC 2,X2↔FMPR 2,Z3
	LAC Z2↔FMPR X3↔FSBR 2,0↔FMPR 2,Y1↔FADR 1,2↔LAC 3,Y2↔FMPR 3,X3
	LAC X2↔FMPR Y3↔FSBR 3,0↔FMPR 3,Z1↔FADR 1,3↔DAC 1,KK(F)
	MOVMS 1↔CAML 1,[1.0]↔GO L4	;SKIP KK TOO SMALL.
	CAME E,E0↔GO L3

;AA(F) ← (Z1*(Y2-Y3) + Z2*(Y3-Y1) + Z3*(Y1-Y2)).
L4:	LAC 1,Y2↔FSBR 1,Y3↔FMPR 1,Z1↔LAC 0,1
	LAC 1,Y3↔FSBR 1,Y1↔FMPR 1,Z2↔FADR 0,1
	LAC 1,Y1↔FSBR 1,Y2↔FMPR 1,Z3↔FADR 0,1↔DAC AA(F)↔FMPR↔DAC ABC

;BB(F) ← (X1*(Z2-Z3) + X2*(Z3-Z1) + X3*(Z1-Z2)).
	LAC 1,Z2↔FSBR 1,Z3↔FMPR 1,X1↔LAC 0,1
	LAC 1,Z3↔FSBR 1,Z1↔FMPR 1,X2↔FADR 0,1
	LAC 1,Z1↔FSBR 1,Z2↔FMPR 1,X3↔FADR 0,1↔DAC BB(F)↔FMPR↔FADRM ABC

;CC(F) ← (X1*(Y3-Y2) + X2*(Y1-Y3) + X3*(Y2-Y1)).
	LAC 1,Y3↔FSBR 1,Y2↔FMPR 1,X1↔LAC 0,1
	LAC 1,Y1↔FSBR 1,Y3↔FMPR 1,X2↔FADR 0,1
	LAC 1,Y2↔FSBR 1,Y1↔FMPR 1,X3↔FADR 0,1↔DAC CC(F)↔FMPR↔FADRM ABC

;NORMALIZE.
	CALL(SQRT↑,ABC)↔MOVSI(<1.0>)↔FDVR 0,1
	FMPRM AA(F)↔FMPRM BB(F)↔FMPRM CC(F)↔FMPRM KK(F)
	TLNN ARG,(BBIT)↔POP1J↔GO L1
ENDR FACOEF;1/14/73(BGB)---------------------------------------------
COMMENT ⊗ ENORM & VNORM

SUBR(ENORM,BODY)	     ;COMPUTE EDGE NORMALS FROM FACE NORMALS.
COMMENT .-----------------------------------------------------------.
 	ACCUMULATORS{E,F1,F2}
	LAC E,BODY
L1:	PED E,E↔CAMN E,BODY↔POP1J
	PFACE F1,E↔NFACE F2,E
	LAC AA(F1)↔FAD AA(F2)↔FSC -1↔MOVNM AA(E)
	LAC BB(F1)↔FAD BB(F2)↔FSC -1↔MOVNM BB(E)
	LAC CC(F1)↔FAD CC(F2)↔FSC -1↔MOVNM CC(E)
	GO L1
ENDR ENORM;1/14/73(BGB)----------------------------------------------

SUBR(VNORM,BODY)	;COMPUTE VERTEX NORMALS FROM EDGE NORMALS.
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS{V,E,E0,A,B,C}
	LAC V,BODY
L1:	PVT V,V↔CAMN V,BODY↔POP1J
	PED E,V↔SKIPN E0,E↔POP1J   ;VERTEX BODY CASE.
	SETZB 0,A↔SETZB B,C
L2:	FAD A,AA(E)↔FAD B,BB(E)↔FAD C,CC(E)
	PVT 1,E↔CAME 1,V↔GO .+3↔PCW E,E↔GO .+5
	NVT 1,E↔CAME 1,V↔AOJA .+5↔NCW E,E
	CAME E,E0↔AOJA L2↔AOS
	FLOAT↔FDV A,↔FDV B,↔FDV C,
	DAC A,XPP(V)↔DAC B,YPP(V)↔DAC C,ZPP(V)
	GO L1
ENDR VNORM;1/14/73(BGB)----------------------------------------------

⊗
SUBN(ZCLIPF,FACE,CAMERA)
COMMENT .-----------------------------------------------------------.

;GET A PZZ VERTEX OF F0  -  PZZ ≡ BEHIND THE CAMERA.
L0:	LAC 1,FACE
	DAC 1,F0↔DAC 1,U1↔DAC 1,F
	PED 0,1↔DAC E

L1:	SETQ(E,{ECCW,E,F})
	SETQ(V,{VCCW,E,F})
	TEST 1,PZZ↔GO L1

;GET FIRST NZZ VERTEX CCW AROUND F FROM E  -  NZZ ≡ INVIEW.
L2:	SETQ(E,{ECCW,E,F})
	SETQ(V,{VCCW,E,F})
	TEST 1,NZZ↔GO L2

;MAKE Z-CLIP VERTEX.
	LAC 1,E↔PVT 0,1↔CAMN 0,V↔GO .+3↔CALL(INVERT,E)
	PVT 0,1↔DAC V1
	NVT 0,1↔DAC V2
	SETQ(U2,{ESPLIT↑,E})
	LAC 1,U2↔MARK 1,TMPBIT
	CALL(ZCLIP,V1,U2,V2,CAMERA)
	CALL(UNPROJECT,U2,CAMERA)
	LAC 1,U2↔MARK 1,NZZ

;MAKE Z-CLIP EDGE.
L3:	LAC 1,U1↔TEST 1,VBIT↔GO L4	;U1 IS FACE ON 1ST TIME THRU.
	SETQ(ENEW,{MKFE↑,U1,F,U2})
	LAC 2,ENEW↔MARK 2,TMPBIT	;NEW EDGE IS TEMPORARY.
	NFACE 1,2↔MARK 1,PZZ		;NEW FACE IS BEHIND THE CAMERA.
	EXCH 1,F↔MARKZ 1,PZZ↔MARK 1,NZZ	;OLD FACE IS INVIEW.
	CAMN  1,F0↔POP2J↔GO .+3		;  ...EXIT OR PASS OVER.
L4:	LAC U2↔DAC U0

;ADVANCE INTO THE NEXT FACE.
	LAC U2↔DAC U1
	SETQ(F,{OTHER,E,F})
	CAME 1,F0↔GO L2
	LAC U0↔DAC U2↔GO L3
DECLARE{F,E,V,V1,V2,U0,U1,U2,ENEW,F0}
ENDR ZCLIPF;1/14/73(BGB)---------------------------------------------
SUBN(FMRK,WORLD)		;MARK POTENT FACES.
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS{W,B,F,Q,R}

;INITIALIZE THE WORLD'S POTENTIALLY VISIBLE FACE AND EDGE LISTS.
	LAC 1,WORLD↔SETZ
	PFACE. 0,1↔PED. 0,1↔NED. 0,1
	NCAMR 1,1↔DAC 1,CAMERA#

;FOR ALL THE BODIES OF THE WORLD.
	LAC B,WORLD↔DAC B,BODY#
L1:	LAC B,BODY↔CCW B,B↔DAC B,BODY
	CAMN B,WORLD↔POP1J
	PED 1,B↔TEST 1,EBIT↔POP1J	;DON'T LOOK AT SINGLE POINTS

;FOR ALL THE FACES OF EACH BODY.
	LAC F,B
L2:	PFACE F,F↔DAC F,FACE#
	CAMN F,BODY↔GO L1
	MARKZ F,VISIBLE+POTENT	;HIDE.
	TEST F,NZZ↔GO L2	;FACE IS FULLY BEHIND THE CAMERA.
	TEST F,PZZ↔GO L3	;FACE IS PARTIALLY IN VIEW.
	CALL(ZCLIPF,F,CAMERA)	;DO Z-CLIPPING.
	LAC F,FACE
L3:	PUSH P,F↔MOVNS(P)↔CALL(FACOEF)	;-F FOR PP COORDINATES.
	LAC F,FACE↔SETZ↔ALT. 0,F
	LAC CC(F)↔FSC =17	; TIMES 2↑17 = 131,072.
	CAML KK(F)↔GO L2	;FACE HAS BACKSIDE TOWARDS CAMERA.

;POTENTIALLY VISIBLE FACE.
L4:	MARK F,POTENT
	MARKZ F,TBIT1
	LAC 1,WORLD↔PFACE 0,1
	POTEN. 0,F↔PFACE. F,1
	GO L2
ENDR FMRK;1/14/73(BGB)-----------------------------------------------
SUBN(EMRK,WORLD)		;MARK POTENT EDGES FOR OCCULT.
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS{Q,R,S,B,F1,F2,E,A}
	ACCUMULATORS{V1,V2}

;FOR ALL THE BODIES OF THE WORLD.
	LAC B,WORLD
L1:	CCW B,B↔CAMN B,WORLD↔POP1J
;FOR ALL THE EDGES OF EACH BODY.
	LAC E,B
L2:	PED E,E↔CAMN E,B↔GO L1
	SETZM↔POTEN. 0,(E)
	MARKZ E,FOLDED+VISIBLE+POTENT
	PFACE F1,E
	NFACE F2,E

;WHEN EITHER FACE IS POTENT THEN THE EDGE IS POTENT.
	LAC(F1)↔IOR(F2)↔TLNN(POTENT)↔GO L2
	MARK E,POTENT
;CONS THE EDGE INTO THE WORLD'S POTENTIALLY VISIBLE EDGE LIST.
	LAC 1,WORLD↔PED 0,1↔SKIPN↔NED. E,1
	PED. E,1↔POTEN. 0,E↔SETZ↔UFACE. 0,E	;CLEAR UFACE(E).
	CALL(ECOEF,E)
	MARK V1,POTENT↔IORM(V2)

;WHEN ONLY ONE FACE IS POTENT THEN EDGE IS FOLDED.
	LAC(F1)↔XOR(F2)↔TLNN(POTENT)↔GO L2
	TEST F1,POTENT↔GO[CALL(INVERT↑,E)↔GO .+1];NOTA BENE !
	MARK E,FOLDED↔IORM(V1)↔IORM(V2)
	SETO↔UFACE. 0,E	;EMPTY UNDER FACE OF FOLDS.
	GO L2
ENDR EMRK;1/14/73(BGB)-----------------------------------------------

;COMPUTE NORMALIZED EDGE COEFFICIENTS.
SUBR(ECOEF,EDGE)
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS{V1,V2,S,B,F1,F2,E,A,FLG}	;BUT ONLY V1,V2,E,S.
	LAC E,EDGE↔NVT V1,E↔PVT V2,E
	LAC YPP(V2)↔FSBR YPP(V1)↔DAC AA(E)↔FMPR↔DAC 1
	LAC XPP(V1)↔FSBR XPP(V2)↔DAC BB(E)↔FMPR↔FADR 1,0
	LAC XPP(V2)↔FMPR YPP(V1)
	LAC S,XPP(V1)↔FMPR S,YPP(V2)↔FSBR S↔DAC CC(E)
	CALL(SQRT↑,1)↔MOVSI(<1.0>)↔FDVR 0,1
	FMPRM AA(E)↔FMPRM BB(E)↔FMPRM CC(E)
	POP1J
ENDR ECOEF;7/23/73(BGB)----------------------------------------------
SUBN(ZCLIP,VERT1,VERTU,VERT2,CAMERA)
COMMENT .-----------------------------------------------------------.
	F←0 ↔ U←1
	ACCUMULATORS{V1,V2,X1,Y1,Z1,X2,Y2,Z2,C}
	SAVAC(11)
	LAC C,CAMERA
;V1 BEHIND CAMERA PLANE, V2 VEFORE CAMERA PLANE.
	CDR V1,VERT1
	CDR  U,VERTU
	CDR V2,VERT2
	LAC F,3(C)	;FOCAL.

;UNPROJECT TO CAMERA CENTERED COORDINATES.
	FOR @$ I←1,2{
	LAC Z$I,-1(C)↔FDVR Z$I,ZPP(V$I)
	LAC Y$I,Z$I↔ FMPR Y$I,YPP(V$I)↔ FDVR Y$I,-2(C)
	LAC X$I,Z$I↔ FMPR X$I,XPP(V$I)↔ FDVR X$I,-3(C)}

;PIERCE Z=-FOCAL PLANE BY SIMILAR TRIANGLES & REPROJECT.
	FSBR X1,X2↔ FSBR Y1,Y2↔ FSBR Z1,Z2
	FADR Z2,F↔MOVNS Z2

	FMPR X1,Z2↔FDVR X1,Z1↔FADR X1,X2
	FMPR X1,-3(C)↔FDVR X1,F↔MOVNM X1,XPP(U)

	FMPR Y1,Z2↔FDVR Y1,Z1↔FADR Y1,Y2
	FMPR Y1,-2(C)↔FDVR Y1,F↔MOVNM Y1,YPP(U)
	MOVM 2,-1(C)↔FDVR 2,F↔DAC 2,ZPP(U)
;....................................................................
;MARK U'S NSEW BITS.
	ACCUMULATORS{XX,YY}
	LAC XX,XPP(U)↔FMPR XX,MAG↔FADR XX,SOX↔XDC. XX,U↔HLLES XX
	LAC YY,YPP(U)↔FMPR YY,MAG↔FADR YY,SOY↔YDC. YY,U↔HLLES YY
	TYPE 0,U↔TRZ(NSEW)	;NSEW RESET.
	CAMLE YY,FYH↔TRO(NORTH)
	CAMGE YY,FYL↔TRO(SOUTH)
	CAMLE XX,FXH↔TRO(EAST)
	CAMGE XX,FXL↔TRO(WEST)
	TRZ(PZZ)↔TRO(NZZ)
	TYPE. 0,U
	GETAC(11)↔POP4J
ENDR;1/14/73(BGB)------------------------------------------------------
SUBN(XYCLIP)
COMMENT .------------------------------------------------------------
;XY-CLIPPER, skips when portion is visible;
;expect arguments in accumulators V1 & V2;
;returns results via accumulator PTR.
	ACCUMULATORS{E,V1,V2,X1,Y1,X2,Y2,PTR}

;GET NSEW BITS.
	LDB 0,[POINT 4,(V1),8];
	LDB 1,[POINT 4,(V2),8];
	TRNE 0,(1)↔POP0J			;EASY OUTSIDER.
	XDC X1,V1↔YDC Y1,V1			;GET ENDS' LOCII.
	XDC X2,V2↔YDC Y2,V2

;EASY INSIDER VERTICES.
	JUMPE 0,[LAC X1↔FIXX↔DIP(PTR)		;EDGE'S DISPLAY
	 LAC Y1↔FIXX↔DAP(PTR)↔AOBJN PTR,.+1]	;COORDINATES.
	JUMPE 1,[LAC X2↔FIXX↔DIP(PTR)
	 LAC Y2↔FIXX↔DAP(PTR)↔AOBJN PTR,.+1↔GO L]

;COMPUTE EDGE COEFFICIENTS.
	LAC Y1↔FSBR Y2↔DAC A
	LAC X2↔FSBR X1↔DAC B
	LAC X2↔FMPR Y1↔MOVNM C
	LAC X1↔FMPR Y2↔FADRM C

;PARTIAL PRODUCTS.
	LAC A↔FMPR FXH↔DAC AXH
	LAC A↔FMPR FXL↔DAC AXL
	LAC B↔FMPR FYH↔DAC BYH
	LAC B↔FMPR FYL↔DAC BYL

;CORNER Q'S.
	SETOM FLGO↔SETZM FLGZ
	LAC AXH↔FADR BYH↔FADR C↔DAC QNE↔ANDM FLGO↔IORM FLGZ
	LAC AXL↔FADR BYH↔FADR C↔DAC QNW↔ANDM FLGO↔IORM FLGZ
	LAC AXL↔FADR BYL↔FADR C↔DAC QSW↔ANDM FLGO↔IORM FLGZ
	LAC AXH↔FADR BYL↔FADR C↔DAC QSE↔ANDM FLGO↔IORM FLGZ

;HARD OUTSIDER CASES.
	SKIPGE FLGO↔POP0J
	SKIPL  FLGZ↔POP0J
;XY-CLIPPER continued.
;NORTH BORDER CROSSING.
	LAC QNE↔XOR QNW↔SKIPL↔GO L2
	LAC Y1↔CAMGE Y2↔LAC Y2↔CAMG FYH↔GO L2
	LAC BYH↔FADR C↔MOVNS↔FDVR A↔FIXX↔DIP(PTR)
	LAC YH↔DAP(PTR)
	AOBJN PTR,.+2↔GO L

;SOUTH BORDER CROSSING.
L2:	LAC QSE↔XOR QSW↔SKIPL↔GO L3
	LAC Y1↔CAMLE Y2↔LAC Y2↔CAML FYL↔GO L3
	LAC BYL↔FADR C↔MOVNS↔FDVR A↔FIXX↔DIP(PTR)
	LAC YL↔DAP(PTR)
	AOBJN PTR,.+2↔GO L

;EAST BORDER CROSSING.
L3:	LAC QSE↔XOR QNE↔SKIPL↔GO L4
	LAC X1↔CAMGE X2↔LAC X2↔CAMG FXH↔GO L4
	LAC XH↔DIP(PTR)
	LAC AXH↔FADR C↔MOVNS↔FDVR B↔FIXX↔DAP(PTR)
	AOBJN PTR,.+2↔GO L

;WEST BORDER CROSSING.
L4:	LAC QSW↔XOR QNW↔SKIPL↔GO L5
	LAC X1↔CAMLE X2↔LAC X2↔CAML FXL↔GO L5
	LAC XL↔DIP(PTR)
	LAC AXL↔FADR C↔MOVNS↔FDVR B↔FIXX↔DAP(PTR)
	AOBJN PTR,.+2↔GO L

;STRANGE EXIT - VMARK & ECOEF ARE INCONSISTENT.
L5:	OUTSTR[ASCIZ/XY-CLIPPER FALL THRU !
/]↔	POP0J

;VISIBLE PORTION EXIT.
L:	AOS(P)↔POP0J
	DECLARE{A,B,C,FLGO,FLGZ,AXH,AXL,BYH,BYL,QNE,QNW,QSW,QSE}
ENDR XYCLIP;1/14/73(BGB)---------------------------------------------
	DECLARE{FXL,FXH,FYL,FYH}	;FLOATING WINDOW.
SUBR(CLIPER,WINDOW)
COMMENT .-----------------------------------------------------------.
	ACCUMULATORS{E,V1,V2,X1,Y1,X2,Y2,PTR,S12,B}
	X←←X1 ↔ Y←←Y1 ↔ V←←V1

	SETZM LINK		;SET VISIBLE EDGE LIST TO NIL.

;GET THE 2-D CLIP WINDOW FRAME.
	LAC 1,WINDOW↔NCAMR 0,1↔DAC CAMERA#
	HLRE 1(1)↔DAC XL↔FLOAT↔DAC FXL
	HRRE 1(1)↔DAC XH↔FLOAT↔DAC FXH
	HLRE 2(1)↔DAC YL↔FLOAT↔DAC FYL
	HRRE 2(1)↔DAC YH↔FLOAT↔DAC FYH

;WINDOW SOURCE-OBJECT MAPPING.
	LAC -1(1)↔DAC MAG
	HLRE 2,-3(1)↔FLOAT 2,↔FMPR 2,MAG
	HLRE 0,-2(1)↔FLOAT↔FSB 2↔DAC SOX
	HRRE 2,-3(1)↔FLOAT 2,↔FMPR 2,MAG
	HRRE 0,-2(1)↔FLOAT↔FSB 2↔DAC SOY

;2-D BODIES OF THE WINDOW'S CAMERA'S PREDICTED & PERCEIVED IMAGES.
	LAC B,WINDOW
	NCAMR B,B↔PIMAG B,B↔SKIPE B↔CALL(XCLIP)	;PERCIEVED IMAGE BODIES.
	LAC B,WINDOW
	NCAMR B,B↔SIMAG B,B↔SKIPE B↔CALL(XCLIP)	;PREDICTED IMAGE BODIES.

;3-D BODIES OF THE WORLD.
	LAC B,WINDOW
	NCAMR B,B↔PWRLD B,B↔CALL(XCLIP)
	LAC 1,LINK↔PED. 1,B↔POP1J
;--------------------------------------------------------------------
XCLIP:		;CLIP BODY RING.
COMMENT .-----------------------------------------------------------.
L1:	CCW B,B			;SCAN THE BODIES OF A WORLD OR IMAGE.
	TEST B,BBIT↔POPJ P,
	LAC V,B			;SCAN THE VERTICES OF EACH BODY.
	PVT V,V↔CAME V,B↔GO[
;....................................................................
;COMPUTE DISPLAY COORDINATES OF A VERTEX.
	LAC X,XPP(V)↔FMPR X,MAG↔FADR X,SOX↔XDC. X,V↔HLLES X
	LAC Y,YPP(V)↔FMPR Y,MAG↔FADR Y,SOY↔YDC. Y,V↔HLLES Y

;COMPARE VERTEX WITH WINDOW.
	LAC 0,(V) ↔TLZ(NSEW)		;RESET NSEW TYPE BITS.
	CAMLE Y,FYH↔TLO(NORTH)
	CAMGE Y,FYL↔TLO(SOUTH)
	CAMLE X,FXH↔TLO(EAST)
	CAMGE X,FXL↔TLO(WEST)
	DAC 0,(V) ↔GO .-2]
;....................................................................
;TEST EDGE DISPLAY CONDITIONS.
	LAC E,B
L2:	PED E,E↔CAMN E,B↔GO L1		;SCAN THE EDGES OF EACH BODY.
	TESTZ E,DARKEN↔GO L2		;DON'T DISPLAY DARKEND EDGES.
	SKIPE ALLSHARP↔GO L2B		;WHEN ALLSHARP, IGNORE NSHARP.
	TESTZ E,FOLDED↔GO L2A		;WHEN FOLDED, IGNORE NSHARP.
	TESTZ E,NSHARP↔GO L2		;DON'T DISPLAY NOT-SHARP EDGES.
L2A:	TEST  E,VISIBLE∨POTENT↔GO L2	;MUST BE VISIBLE OR POTENT.
L2B:	PVT V1,E↔NVT V2,E		;ENDS OF THE EDGE.
	MOVEI PTR,U			;PSEUDO VERTEX FOR ZCLIP.

;PZZ ON WHEN VERTEX IS BEHIND THE CAMERA.
	TESTZ V2,PZZ↔EXCH V1,V2	;INSURE V2 IS INVIEW, IF EITHER BE.
	TESTZ V2,PZZ↔GO L2	;EDGE IS FULLY BEHIND THE CAMERA.
	TEST  V1,PZZ↔GO L3	;EDGE IS FULLY BEFORE THE CAMERA.

;Z-CLIP IF NEEDED, XY-CLIP TO COMPUTE DISPLAY COORDINATES OF EDGE.
	SETQ(V1,{ZCLIP,V1,PTR,V2,CAMERA})
L3:	MOVSI PTR,-2↔HRRI PTR,-3(E)	;AOBJN PTR FOR XY-CLIP.
	CALL(XYCLIP)↔GO L2		;EDGE NOT VISIBLE IN WINDOW.

;CONS A VISIBLE EDGE INTO VISIBLE EDGE LIST.
	MARK E,VISIBLE			;EDGE IS VISIBLE IN WINDOW.
	LAC 1,LINK↔ALT2. 1,E
	DAC E,LINK↔GO L2
;DATA.
	0↔0↔0↔U: BLOCK 9		;PSEUDO VERTEX FOR Z-CLIPPER.
	LINK:0				;HEAD OF VISIBLE EDGE LIST.
ENDR;2/5/73(BGB)-----------------------------------------------------
END