home *** CD-ROM | disk | FTP | other *** search
- program chap2_11;
-
- uses graph, crt;
-
- const xoffset=640/2;
- yoffset=480/2;
- xscale=1;
- yscale=-1;
- persp=500;
-
- type point=record
- xw, yw, zw : real;
- xs, ys, zs : integer;
- end;
-
- matrix_4x4=array[1..4,1..4] of real;
-
- var vertex : array[1..18] of point;
- faces : array[1..13,1..6] of word; {First entry is face colour}
- face_list : array[1..13,1..2] of integer; {First entry is face, second is depth}
- polygon : array[1..15] of PointType;
- f : text;
- c, c2 : integer;
- ch : char;
- w2v, temp, temp2 : matrix_4x4;
-
- procedure Initialise_Graphics;
- var Graphdriver, Graphmode, Errorcode : integer;
- begin
- Graphdriver:=Detect;
- InitGraph(Graphdriver, Graphmode,'');
- Errorcode:=graphresult;
- if Errorcode<>grOk then
- begin
- writeln('Graphics Error: ',GraphErrorMsg(ErrorCode));
- writeln('Program Aborted');
- Halt(1);
- end;
- SetLineStyle(0,0,3);
- end;
-
- procedure translate(x,y,z : real; var m : matrix_4x4);
- begin
- m[1,1]:=1; m[2,1]:=0; m[3,1]:=0; m[4,1]:=0;
- m[1,2]:=0; m[2,2]:=1; m[3,2]:=0; m[4,2]:=0;
- m[1,3]:=0; m[2,3]:=0; m[3,3]:=1; m[4,3]:=0;
- m[1,4]:=x; m[2,4]:=y; m[3,4]:=z; m[4,4]:=1;
- end;
-
- procedure rotate_x(t : real; var m : matrix_4x4);
- begin
- m[1,1]:=1; m[2,1]:=0; m[3,1]:=0; m[4,1]:=0;
- m[1,2]:=0; m[2,2]:=cos(t); m[3,2]:=sin(t); m[4,2]:=0;
- m[1,3]:=0; m[2,3]:=-sin(t); m[3,3]:=cos(t); m[4,3]:=0;
- m[1,4]:=0; m[2,4]:=0; m[3,4]:=0; m[4,4]:=1;
- end;
-
-
- procedure rotate_y(t : real; var m : matrix_4x4);
- begin
- m[1,1]:=cos(t); m[2,1]:=0; m[3,1]:=-sin(t); m[4,1]:=0;
- m[1,2]:=0; m[2,2]:=1; m[3,2]:=0; m[4,2]:=0;
- m[1,3]:=sin(t); m[2,3]:=0; m[3,3]:=cos(t); m[4,3]:=0;
- m[1,4]:=0; m[2,4]:=0; m[3,4]:=0; m[4,4]:=1;
- end;
-
- procedure rotate_z(t : real; var m : matrix_4x4);
- begin
- m[1,1]:=cos(t); m[2,1]:=sin(t); m[3,1]:=0; m[4,1]:=0;
- m[1,2]:=-sin(t); m[2,2]:=cos(t); m[3,2]:=0; m[4,2]:=0;
- m[1,3]:=0; m[2,3]:=0; m[3,3]:=1; m[4,3]:=0;
- m[1,4]:=0; m[2,4]:=0; m[3,4]:=0; m[4,4]:=1;
- end;
-
- procedure mult_4x4(a,b : matrix_4x4; var m : matrix_4x4);
- var c : integer;
- begin
- for c:=1 to 4 do
- m[c,1]:=a[1,1]*b[c,1]+a[2,1]*b[c,2]+a[3,1]*b[c,3]+a[4,1]*b[c,4];
- for c:=1 to 4 do
- m[c,2]:=a[1,2]*b[c,1]+a[2,2]*b[c,2]+a[3,2]*b[c,3]+a[4,2]*b[c,4];
- for c:=1 to 4 do
- m[c,3]:=a[1,3]*b[c,1]+a[2,3]*b[c,2]+a[3,3]*b[c,3]+a[4,3]*b[c,4];
- for c:=1 to 4 do
- m[c,4]:=a[1,4]*b[c,1]+a[2,4]*b[c,2]+a[3,4]*b[c,3]+a[4,4]*b[c,4];
- end;
-
- procedure draw_face(face: integer);
- var x1,y1,z1,x2,y2,z2 : integer;
- count, c : integer;
- begin
- count:=0;
- {Copy vertices to polygon}
- for c:=2 to 6 do
- begin
- if faces[face,c]<>0 then
- begin
- polygon[c-1].x:=vertex[faces[face,c]].xs;
- polygon[c-1].y:=vertex[faces[face,c]].ys;
- inc(count);
- end;
- end;
-
- {Draw polygon}
- SetFillStyle(1,(faces[face,1]));
- FillPoly(count,polygon);
- end;
-
- procedure draw_picture;
- var c, c2, max_z : integer;
- any_swapped : boolean;
- begin
- {Put faces into a list and find each's furthest distance}
- for c:=1 to 13 do
- begin
- face_list[c,1]:=c;
- max_z:=-9999;
- for c2:=2 to 6 do
- begin
- if faces[c,c2]<>0 then
- if vertex[faces[c,c2]].zs>max_z then max_z:=vertex[faces[c,c2]].zs;
- end;
- face_list[c,2]:=max_z;
- end;
-
- {Bubble sort into decreasing depth order}
- repeat
- any_swapped:=false;
- for c:=1 to 12 do
- begin
- if face_list[c+1,2]>face_list[c,2] then
- begin
- c2:=face_list[c+1,2];
- face_list[c+1,2]:=face_list[c,2];
- face_list[c,2]:=c2;
- c2:=face_list[c+1,1];
- face_list[c+1,1]:=face_list[c,1];
- face_list[c,1]:=c2;
- any_swapped:=true;
- end;
- end;
- until any_swapped=false;
-
- ClearDevice;
- for c:=1 to 13 do
- draw_face(face_list[c,1]);
- end;
-
- procedure transform(m : matrix_4x4);
- var c : integer;
- begin
- for c:=1 to 18 do
- begin
- vertex[c].zs:=round(vertex[c].xw*m[3,1]+vertex[c].yw*m[3,2]+vertex[c].zw*m[3,3]+m[3,4]);
- vertex[c].xs:=round(((vertex[c].xw*m[1,1]+vertex[c].yw*m[1,2]+vertex[c].zw*m[1,3]+m[1,4])
- *(persp/vertex[c].zs)*xscale)+xoffset);
- vertex[c].ys:=round(((vertex[c].xw*m[2,1]+vertex[c].yw*m[2,2]+vertex[c].zw*m[2,3]+m[2,4])
- *(persp/vertex[c].zs)*yscale)+yoffset);
- end;
- end;
-
-
- begin
- clrscr;
- writeln; writeln; writeln; writeln;
- writeln('This is from Chapter 2 Step 11 of the Virtual Reality Homebrewer''s Handbook');
- writeln('and shows how to move around a virtual shape drawn with depth sorted, ');
- writeln('flat shaded faces.');
- writeln;
- writeln;
- writeln('Controls: 8/2 - move forwards/back');
- writeln(' 4/6 - move left/back');
- writeln(' 7/1 - move up/down');
- writeln(' o/l - pitch up/down');
- writeln(' </> - yaw left/right');
- writeln(' n/m - roll left/right');
- writeln;
- writeln(' q - quit');
- writeln;
- writeln(' Press any key to continue');
- ch:=ReadKey;
-
- {Read in vertices}
- assign(f,'points.dat');
- reset(f);
- for c:=1 to 18 do
- begin
- readln(f,vertex[c].xw,vertex[c].yw,vertex[c].zw);
- end;
- close(f);
-
- {Read in faces}
- assign(f,'faces.dat');
- reset(f);
- for c:=1 to 13 do
- for c2:=1 to 6 do
- read(f,faces[c,c2]);
- close(f);
-
- {Move to z=500}
- for c:=1 to 18 do
- begin
- vertex[c].zw:=vertex[c].zw+500;
- end;
-
- Initialise_Graphics;
-
- translate(-500,-400,0,w2v);
- Rotate_Y(pi/5,temp);
- mult_4x4(w2v,temp,w2v);
- Rotate_X(-pi/6,temp);
- mult_4x4(w2v,temp,w2v);
-
- transform(w2v);
- draw_picture;
-
- repeat
- ch:=Readkey;
- case ch of
- '8': begin
- translate(0,0,-10,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- '2': begin
- translate(0,0,10,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- '4': begin
- translate(10,0,0,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- '6': begin
- translate(-10,0,0,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- '1': begin
- translate(0,10,0,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- '7': begin
- translate(0,-10,0,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- ',': begin
- rotate_y(PI/180,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- '.': begin
- rotate_y(-PI/180,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- 'm': begin
- rotate_z(PI/180,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- 'n': begin
- rotate_z(-PI/180,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- 'o': begin
- rotate_x(PI/180,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- 'l': begin
- rotate_x(-PI/180,temp);
- mult_4x4(w2v,temp,temp2);
- w2v:=temp2;
- end;
- end;
- transform(w2v);
- draw_picture;
- until ch='q';
- CloseGraph;
- end.