(******************************************************************************
* POLY3I11.MOD *
* ABO Software Dep. *
* *
* Purpose : To provide an integer 3D polygon type. *
* *
* Notes : Routines for conversion to and from real polygons are included. *
* *
* Version Date : 22/10/92 *
******************************************************************************)
IMPLEMENTATION MODULE POLY3I1;
IMPORT IO;
FROM PNT3I1 IMPORT Point3I,normal,debugp,topoint3D,topoint3I;
FROM PNT3D1 IMPORT Point3D,neg;
FROM TRAN3D1 IMPORT viewtrans;
FROM LGHT3D1 IMPORT shade;
FROM SCAN3D2 IMPORT scanpoly3I;
PROCEDURE topoly3D(
p1 :Poly3I):Poly3D;
VAR
p:Poly3D;
i:INTEGER;
BEGIN
p.N:=p1.N;
FOR i:=1 TO p.N DO
p.P[i]:=topoint3D(p1.P[i]);
END;
RETURN(p);
END topoly3D;
PROCEDURE topoly3I(
p1 :Poly3D):Poly3I;
VAR
p:Poly3I;
i:INTEGER;
BEGIN
p.N:=p1.N;
FOR i:=1 TO p.N DO
p.P[i]:=topoint3I(p1.P[i]);
END;
RETURN(p);
END topoly3I;
PROCEDURE polynormal(
poly:Poly3I):Point3I;
BEGIN
RETURN(normal(poly.P[1],poly.P[2],poly.P[poly.N]));
END polynormal;
PROCEDURE clippoly(VAR poly:Poly3I;view:View3D):BOOLEAN;
TYPE
Edge = (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax);
VAR
e:Edge;
vmax,vmin:Point3I;
PROCEDURE clippolyedge(polyin :Poly3I;
edge :Edge;
VAR polyout:Poly3I);
VAR
i:INTEGER;
s,p:Point3I;
PROCEDURE output(p:Point3I);
BEGIN
polyout.N:=polyout.N+1;
polyout.P[polyout.N]:=p;
END output;
PROCEDURE inedge(p:Point3I):BOOLEAN;
VAR
in:BOOLEAN;
BEGIN
CASE edge OF
|Xmin:
in:=(vmin.X
p.X);
|Ymin:
in:=(vmin.Yp.Y);
|Zmin:
in:=(vmin.Zp.Z);
END;
RETURN(in);
END inedge;
PROCEDURE intersect(p0,p1:Point3I):Point3I;
VAR
n,d:LONGINT;
p:Point3I;
BEGIN
CASE edge OF
|Xmin:
n:=(vmin.X-p0.X);
d:=(p1.X-p0.X);
p.X:=vmin.X;
p.Y:=p0.Y + (n*(p1.Y-p0.Y)) DIV d;
p.Z:=p0.Z + (n*(p1.Z-p0.Z)) DIV d;
|Xmax:
n:=(vmax.X-p0.X);
d:=(p1.X-p0.X);
p.X:=vmax.X;
p.Y:=p0.Y + (n*(p1.Y-p0.Y)) DIV d;
p.Z:=p0.Z + (n*(p1.Z-p0.Z)) DIV d;
|Ymin:
n:=(vmin.Y-p0.Y);
d:=(p1.Y-p0.Y);
p.X:=p0.X + (n*(p1.X-p0.X)) DIV d;
p.Y:=vmin.Y;
p.Z:=p0.Z + (n*(p1.Z-p0.Z)) DIV d;
|Ymax:
n:=(vmax.Y-p0.Y);
d:=(p1.Y-p0.Y);
p.X:=p0.X + (n*(p1.X-p0.X)) DIV d;
p.Y:=vmax.Y;
p.Z:=p0.Z + (n*(p1.Z-p0.Z)) DIV d;
|Zmin:
n:=(vmin.Z-p0.Z);
d:=(p1.Z-p0.Z);
p.X:=p0.X + (n*(p1.X-p0.X)) DIV d;
p.Y:=p0.Y + (n*(p1.Y-p0.Y)) DIV d;
p.Z:=vmin.Z;
|Zmax:
n:=(vmax.Z-p0.Z);
d:=(p1.Z-p0.Z);
p.X:=p0.X + (n*(p1.X-p0.X)) DIV d;
p.Y:=p0.Y + (n*(p1.Y-p0.Y)) DIV d;
p.Z:=vmax.Z;
END;
RETURN(p);
END intersect;
BEGIN
polyout.N:=0;
s:=polyin.P[polyin.N];
FOR i:= 1 TO polyin.N DO
p:=polyin.P[i];
IF inedge(p) THEN
IF inedge(s) THEN
output(p);
ELSE
output(intersect(s,p));
output(p);
END;
ELSIF inedge(s) THEN
output(intersect(s,p));
END;
s:=p;
END;
END clippolyedge;
BEGIN
vmax:=topoint3I(view.Vmax);
vmin:=topoint3I(view.Vmin);
FOR e:=Xmin TO Zmax DO
clippolyedge(poly,e,poly);
IF poly.N<=2 THEN
RETURN(FALSE);
END;
END;
RETURN(TRUE);
END clippoly;
PROCEDURE displaypoly(
poly:Poly3I;
c :ColorRGB;
view:View3D);
VAR
i :INTEGER;
vnorm :Point3I;
wnorm :Point3D;
BEGIN
wnorm:=topoint3D(polynormal(poly));
FOR i:=1 TO poly.N DO
poly.P[i]:=topoint3I( viewtrans(view.Vtrans, topoint3D(poly.P[i]) ) );
END;
vnorm:=polynormal(poly);
IF (vnorm.Z#0) AND clippoly(poly,view) THEN
IF wnorm.Z>0.0 THEN
wnorm:=neg(wnorm);
END;
c:=shade( topoint3D(poly.P[1]) ,wnorm,c);
scanpoly3I(poly,vnorm,c);
END;
END displaypoly;
PROCEDURE debugpoly(poly:Poly3I);
VAR
i:INTEGER;
BEGIN
IO.WrStr("Points : ");
IO.WrInt(poly.N,4);
IO.WrLn;
FOR i := 1 TO poly.N DO
debugp(poly.P[i]);
END;
END debugpoly;
BEGIN
END POLY3I1.