DIRECTORY G3dBasic, G3dClip, G3dMatrix; G3dClipImpl: CEDAR PROGRAM IMPORTS G3dMatrix EXPORTS G3dClip ~ BEGIN ClippedPair: TYPE ~ G3dClip.ClippedPair; ClippedTriple: TYPE ~ G3dClip.ClippedTriple; Matrix: TYPE ~ G3dClip.Matrix; Quad: TYPE ~ G3dClip.Quad; Triple: TYPE ~ G3dClip.Triple; Wec: TYPE ~ ARRAY[0..6) OF REAL; AWec: PROC [xp: Quad] RETURNS [Wec] ~ { RETURN[[xp.w+xp.x, xp.w-xp.x, xp.w+xp.y, xp.w-xp.y, xp.z, xp.w-xp.z]]; }; Alphas: PUBLIC PROC [xp0, xp1: Quad] RETURNS [a0, a1: REAL, off: BOOL] ~ { wec0: Wec ¬ AWec[xp0]; wec1: Wec ¬ AWec[xp1]; a0 ¬ 0.0; a1 ¬ 1.0; FOR i: NAT IN[0..6) DO IF wec0[i] < 0.0 THEN { IF wec1[i] < 0.0 THEN RETURN[a0, a1, TRUE]; a0 ¬ MAX[a0, wec0[i]/(wec0[i]-wec1[i])]; } ELSE IF wec1[i] < 0.0 THEN a1 ¬ MIN[a1, wec0[i]/(wec0[i]-wec1[i])]; IF a0 > a1 THEN RETURN[a0, a1, TRUE]; ENDLOOP; RETURN[a0, a1, FALSE]; }; Frustum: PUBLIC PROC [p0, p1: Triple, m: Matrix] RETURNS [ct: ClippedTriple] ~ { dif: Quad; a0, a1, w0, w1: REAL; xp0: Quad ¬ G3dMatrix.TransformH[p0, m]; xp1: Quad ¬ G3dMatrix.TransformH[p1, m]; [a0, a1, ct.off] ¬ Alphas[xp0, xp1]; IF ct.off THEN RETURN; dif ¬ [xp1.x-xp0.x, xp1.y-xp0.y, xp1.z-xp0.z, xp1.w-xp0.w]; w0 ¬ 1.0/(xp0.w+a0*dif.w); w1 ¬ 1.0/(xp0.w+a1*dif.w); ct.c0 ¬ [w0*(xp0.x+a0*dif.x), w0*(xp0.y+a0*dif.y), w0*(xp0.z+a0*dif.z)]; ct.c1 ¬ [w1*(xp0.x+a1*dif.x), w1*(xp0.y+a1*dif.y), w1*(xp0.z+a1*dif.z)]; }; FrustumH: PUBLIC PROC [xp0, xp1: Quad] RETURNS [ct: ClippedTriple] ~ { dif: Quad; a0, a1, w0, w1: REAL; [a0, a1, ct.off] ¬ Alphas[xp0, xp1]; IF ct.off THEN RETURN; dif ¬ [xp1.x-xp0.x, xp1.y-xp0.y, xp1.z-xp0.z, xp1.w-xp0.w]; w0 ¬ 1.0/(xp0.w+a0*dif.w); w1 ¬ 1.0/(xp0.w+a1*dif.w); ct.c0 ¬ [w0*(xp0.x+a0*dif.x), w0*(xp0.y+a0*dif.y), w0*(xp0.z+a0*dif.z)]; ct.c1 ¬ [w1*(xp0.x+a1*dif.x), w1*(xp0.y+a1*dif.y), w1*(xp0.z+a1*dif.z)]; }; FrustumD: PUBLIC PROC [xp0, xp1: Quad] RETURNS [cp: ClippedPair] ~ { dif: Quad; a0, a1, w0, w1: REAL; [a0, a1, cp.off] ¬ Alphas[xp0, xp1]; IF cp.off THEN RETURN; dif ¬ [xp1.x-xp0.x, xp1.y-xp0.y, , xp1.w-xp0.w]; w0 ¬ 1.0/(xp0.w+a0*dif.w); w1 ¬ 1.0/(xp0.w+a1*dif.w); cp.c0 ¬ [w0*(xp0.x+a0*dif.x), w0*(xp0.y+a0*dif.y)]; cp.c1 ¬ [w1*(xp0.x+a1*dif.x), w1*(xp0.y+a1*dif.y)]; }; NearH: PUBLIC PROC [q0, q1: Quad] RETURNS [cp: ClippedPair] ~ { w0, w1: REAL; a0: REAL ¬ 0.0; a1: REAL ¬ 1.0; dx: REAL ¬ q1.x-q0.x; dy: REAL ¬ q1.y-q0.y; dw: REAL ¬ q1.w-q0.w; sum0: REAL ¬ q0.w+q0.z; sum1: REAL ¬ q1.w+q1.z; IF sum0 < 0.0 THEN { IF sum1 < 0.0 THEN RETURN[[[0, 0], [0, 0], TRUE]]; a0 ¬ sum0/(sum0-sum1); } ELSE IF sum1 < 0.0 THEN a1 ¬ sum0/(sum0-sum1); IF a0 > a1 THEN RETURN[[[0, 0], [0, 0], TRUE]]; w0 ¬ IF a0 = 0.0 THEN q0.w ELSE q0.w+a0*dw; w1 ¬ IF a1 = 1.0 THEN q1.w ELSE q0.w+a1*dw; cp.c0 ¬ IF w0 = 0 THEN [q0.x+a0*dx, q0.y+a0*dy] ELSE [(q0.x+a0*dx)/w0, (q0.y+a0*dy)/w0]; cp.c1 ¬ IF w1 = 0 THEN [q0.x+a1*dx, q0.y+a1*dy] ELSE [(q0.x+a1*dx)/w1, (q0.y+a1*dy)/w1]; cp.off ¬ FALSE; }; END. L G3dClipImpl.mesa Copyright Σ 1984, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, September 15, 1992 12:46 pm PDT Clipping operations on projected 3d points Divide xp.x by aspect ratio if non-unity. To clip to [0..1] cube: RETURN[[xp.x, xp.w-xp.x, xp.y, xp.w-xp.y, xp.z, xp.w-xp.z]]; To clip to [-1..1] cube: Κ–"cedarcode" style•NewlineDelimiter ™™Jšœ Οeœ6™BJ™,J˜JšΟk œ˜'J˜—šΠbl œžœž˜Jšžœ ˜Jšžœ˜J˜—šœž˜J˜Jšœ žœ˜)Jšœžœ˜,Jšœžœ˜ Jšœžœ˜šœžœ˜ J˜—Jš œžœžœžœžœ˜#—head™*šΟnœžœ žœ ˜'J™)™Jšžœ6™<—J™Jšžœ@˜FJ˜J˜—š  œžœžœžœ žœžœ˜JJ˜J˜J˜ J˜ šžœžœžœž˜šžœ˜šžœ˜Jšžœžœžœ žœ˜+Jšœžœ ˜(J˜—šžœžœž˜Jšœžœ ˜(——Jšžœ žœžœ žœ˜%Jšžœ˜—Jšžœ žœ˜J˜J˜—š œžœžœžœ˜PJ˜ Jšœžœ˜J˜(J˜(J˜$Jšžœžœžœ˜J˜;J˜J˜J˜HJ˜HJ˜J˜—š œžœžœžœ˜FJ˜ Jšœžœ˜J˜$Jšžœžœžœ˜J˜;J˜J˜J˜HJ˜HJ˜J˜—š œžœžœžœ˜DJ˜ Jšœžœ˜J˜$Jšžœžœžœ˜J˜0J˜J˜J˜3J˜3J˜J˜—š œžœžœžœ˜?Jšœžœ˜ Jšœžœ˜Jšœžœ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜šžœ ˜ šžœ˜Jšžœ žœžœžœ˜2J˜J˜—Jšžœžœ žœ˜.—Jšžœ žœžœžœ˜/Jšœžœ žœžœ ˜+Jšœžœ žœžœ ˜+Jš œžœžœ Οsœ žœ‘œ˜XJš œžœž‘œ ‘œ ‘œ‘œ˜XJšœ žœ˜J˜—J™—Jšžœ˜J˜J˜—…— P΄