home *** CD-ROM | disk | FTP | other *** search
/ Solo Programadores 22 / SOLO_22.iso / disk22 / cdemos / lib3d_v2.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-04-14  |  7.9 KB  |  261 lines

  1. { 3D library                                                     }
  2. { Solo Programadores ver. 1.0                                    }
  3. {                                                                }
  4. { Some things about this library:                                }
  5. { * 360 degrees are 1024 values then 90ยบ are 255 values          }
  6. { * Angle3D define a circle with 1024 values                     }
  7. { * SinData are stored in 8 fixed point ;)                       }
  8. {                                                                }
  9. {                               by Crom / Spanish Lords Feb 96   }
  10. Unit Lib3D_v2;
  11. INTERFACE
  12. Const
  13. { 3D origin                                }
  14.   XOrg      : Integer =   0;
  15.   YOrg      : Integer =   0;
  16.   ZOrg      : Integer =  60;
  17. { Center screen                            }
  18.   XCenter   : Integer = 160;
  19.   YCenter   : Integer = 100;
  20. { Number of points in CosTable             }
  21.   NumSinVal = 256*4;
  22.  
  23. Type
  24.   Point3D   = Array [1..3] of Integer;
  25.   Face3D    = Array [1..4] of Integer;
  26.  
  27. Var
  28. { About CosTable array:                    }
  29. {  * Values are stores * 255 = 8 bits      }
  30. {  * Circle is defined in 1024 incs.       }
  31. {    then 90 degrees are 256 values ;)     }
  32.   CosTable  : Array [0..NumSinVal] of Integer;
  33.  
  34. FUNCTION  FastSin         (Angle3D:Integer):Integer;
  35. FUNCTION  FastCos         (Angle3D:Integer):Integer;
  36. PROCEDURE Calc3DRotations (SinX,CosX,SinY,CosY,SinZ,CosZ:Integer;
  37.                            OrgPoints : Array of Point3D;
  38.                        Var DesPoints : Array of Point3D;
  39.                            NumPoints : Word     );
  40. PROCEDURE Proyect         (XScreen, YScreen : Integer; NumPoints : Word;
  41.                            OrgPoints : Array of Point3D;
  42.                        Var DesPoints : Array of Point3D);
  43. FUNCTION  Visible         (X1,Y1,X2,Y2,X3,Y3:Integer):Boolean;
  44. PROCEDURE QuickSortZ      (NumPoints : Word;
  45.                            Points2qS : Array of Point3D;
  46.                        Var Faces2qS  : Array of Face3D);
  47.  
  48. IMPLEMENTATION
  49. Procedure MakeCosTable;
  50. Var
  51.   CntVal : Word;
  52.   CntAng : Real;
  53.   IncDeg : Real;
  54. Begin
  55.   IncDeg := 2*PI/NumSinVal;
  56.   CntAng := IncDeg;
  57.   CntVal := 0;
  58.   Repeat
  59.     CosTable [CntVal] := Round(255*cos(CntAng));
  60.     CntAng := CntAng+IncDeg;
  61.     Inc (CntVal);
  62.   Until CntVal>1024;
  63. End;
  64.  
  65. Function FastSin (Angle3D:Integer):Integer;Assembler;
  66. Asm
  67.   mov  ax,Seg CosTable
  68.   mov  es,ax
  69.   mov  di,Offset CosTable
  70.   mov  dx,Angle3D
  71.   mov  bx,1024
  72.   add  dx,256
  73.   cmp  dx,bx
  74.   jle  @@Ok
  75.   sub  dx,1024
  76. @@Ok:
  77.   shl  dx,1
  78.   add  di,dx
  79.   mov  ax,es:[di]
  80. End;
  81.  
  82. Function FastCos (Angle3D:Integer):Integer;assembler;
  83. Asm
  84.   mov  ax,Seg CosTable
  85.   mov  es,ax
  86.   mov  di,Offset CosTable
  87.   mov  dx,Angle3D
  88.   shl  dx,1
  89.   add  di,dx
  90.   mov  ax,es:[di]
  91. End;
  92.  
  93. Procedure Calc3DRotations (SinX,CosX,SinY,CosY,SinZ,CosZ:Integer;
  94.                                OrgPoints : Array of Point3D;
  95.                            Var DesPoints : Array of Point3D;
  96.                                NumPoints : Word     );
  97. Var
  98.   X1,Y1,Z1  : Integer;
  99.   Aux1,Aux2 : Integer;
  100.   CntPoints : Word;
  101. Begin
  102.   For CntPoints:=0 to NumPoints do
  103.     Begin
  104. {     X1   := (cos(YAngle) * X  - sin(YAngle) * Z);}
  105.       Aux1 := CosY*OrgPoints [CntPoints,1];
  106.       Aux2 := SinY*OrgPoints [CntPoints,3];
  107.       Asm
  108.         mov ax,Aux1;sar ax,8;mov Aux1,ax
  109.         mov ax,Aux2;sar ax,8;mov Aux2,ax
  110.       End;
  111.       X1   := Aux1-Aux2;
  112. {     Z1   := (sin(YAngle) * X  + cos(YAngle) * Z);}
  113.       Aux1 := SinY*OrgPoints [CntPoints,1];
  114.       Aux2 := CosY*OrgPoints [CntPoints,3];
  115.       Asm
  116.         mov ax,Aux1;sar ax,8;mov Aux1,ax
  117.         mov ax,Aux2;sar ax,8;mov Aux2,ax
  118.       End;
  119.       Z1   := Aux1 + Aux2;
  120. {     X    := (cos(ZAngle) * X1 + sin(ZAngle) * Y);}
  121.       Aux1 := CosZ*X1;
  122.       Aux2 := SinZ*OrgPoints [CntPoints,2];
  123.       Asm
  124.         mov ax,Aux1;sar ax,8;mov Aux1,ax
  125.         mov ax,Aux2;sar ax,8;mov Aux2,ax
  126.       End;
  127.       DesPoints  [CntPoints,1] := Aux1 + Aux2;
  128. {     Y1   := (cos(ZAngle) * Y  - sin(ZAngle) * X1);}
  129.       Aux1 := CosZ*OrgPoints [CntPoints,2];
  130.       Aux2 := SinZ*X1;
  131.       Asm
  132.         mov ax,Aux1;sar ax,8;mov Aux1,ax
  133.         mov ax,Aux2;sar ax,8;mov Aux2,ax
  134.       End;
  135.       Y1   := Aux1 - Aux2;
  136. {     Z    := (cos(XAngle) * Z1 - sin(XAngle) * Y1);}
  137.       Aux1 := CosX*Z1;
  138.       Aux2 := SinX*Y1;
  139.       Asm
  140.         mov ax,Aux1;sar ax,8;mov Aux1,ax
  141.         mov ax,Aux2;sar ax,8;mov Aux2,ax
  142.       End;
  143.       DesPoints  [CntPoints,3] := Aux1 - Aux2;
  144. {     Y    := (sin(XAngle)) * Z1 + cos(XAngle) * Y1);}
  145.       Aux1 := SinX*Z1;
  146.       Aux2 := CosX*Y1;
  147.       Asm
  148.         mov ax,Aux1;sar ax,8;mov Aux1,ax
  149.         mov ax,Aux2;sar ax,8;mov Aux2,ax
  150.       End;
  151.       DesPoints  [CntPoints,2] := Aux1 + Aux2;
  152.     End;
  153. End;
  154.  
  155. Procedure Proyect (XScreen, YScreen : Integer; NumPoints : Word;
  156.                    OrgPoints : Array of Point3D;
  157.                Var DesPoints : Array of Point3D);
  158. Var
  159.   CntPoints: Word;
  160. Begin
  161.   For CntPoints:=0 to NumPoints do
  162.     Begin
  163. { Clipping in Z ;}
  164.       If OrgPoints[CntPoints,3]>=Zorg then
  165.         Begin
  166.       { What happen if point are behind me? }
  167.           DesPoints [CntPoints,1]:=320;
  168.           DesPoints [CntPoints,2]:=200;
  169.         End
  170.       else
  171.         Begin
  172.           DesPoints [CntPoints,1]:=
  173.             XScreen+((XOrg*OrgPoints[CntPoints,3]-OrgPoints[CntPoints,1]*ZOrg)div(OrgPoints[CntPoints,3]-ZOrg));
  174.           DesPoints [CntPoints,2]:=
  175.             YScreen+((YOrg*OrgPoints[CntPoints,3]-OrgPoints[CntPoints,2]*ZOrg)div(OrgPoints[CntPoints,3]-ZOrg));
  176.         End;
  177.     End;
  178. End;
  179. { Comprueba si la coordenada z del vector normal al plano definido    }
  180. { por (X1,Y1,Z1),(X2,Y2,Z2),(X3,Y3,Z3) ses positiva o no.             }
  181. { OJO!!! Se definen los puntos de los planos que se ven en el sentido }
  182. { de las agujas del reloj.                                            }
  183. {                                               <rom / Slords Sep 94  }
  184. Function Visible (X1,Y1,X2,Y2,X3,Y3:Integer):Boolean;assembler;
  185. Asm
  186.   mov  cx,X2     { reg dx = (X2-X1)*(Y3-Y1)) }
  187.   mov  bx,X1
  188.   sub  cx,bx
  189.   mov  ax,Y3
  190.   mov  bx,Y1
  191.   sub  ax,bx
  192.   imul cx
  193.   mov  dx,ax
  194.   push dx
  195.   mov  cx,X3     { reg ax = (X3-X1)*(Y2-Y1) }
  196.   mov  bx,X1
  197.   sub  cx,bx
  198.   mov  ax,Y2
  199.   mov  bx,Y1
  200.   sub  ax,bx
  201.   imul cx
  202.   pop  dx
  203.   sub dx,ax    { reg dx =(X2-X1)*(Y3-Y1)-(X3-X1)*(Y2-Y1) }
  204.   js   @@InVisible { Si el resultado de la resta es negativo Invisible,}
  205.   mov  ax,01
  206.   jmp  @@Fin
  207. @@InVisible:
  208.    xor ax,ax
  209. @@Fin:
  210. End;
  211.  
  212. Procedure QuickSortZ (NumPoints:Word;Points2qS:Array of Point3D;Var Faces2qS:Array of Face3D);
  213. Var
  214.   Cnt        : Word;
  215. { Specific sort }
  216.   Procedure QSort (First, Last: Integer; Var Split1: Integer; Var Split2: Integer);
  217.   Var
  218.     AuxFace    : Face3D;
  219.     ZVal       : Integer;
  220.   Begin
  221.     ZVal := Faces2qS[(First+Last) shr 1,4];
  222.     Repeat
  223.       While Faces2qS[First,4] < ZVal do  Inc (First);
  224.         While Faces2qS[Last,4] > ZVal do Dec (Last );
  225.           If First <= Last then
  226.             Begin
  227.               AuxFace         := Faces2qS[First];
  228.               Faces2qS[First] := Faces2qS[Last];
  229.               Faces2qS[Last]  := AuxFace;
  230.               Inc (First);
  231.               Dec (Last);
  232.             End;
  233.     Until First > Last;
  234.     Split1 := First;
  235.     Split2 := Last;
  236.   End;
  237. { Generic QuickSort }
  238.   Procedure QuickSort (First, Last:Integer);
  239.   Var
  240.     SplitPt1, SplitPt2: Integer;
  241.   Begin
  242.     If First < Last then
  243.       Begin
  244.         qSort (First, Last, SplitPt1, SplitPt2);
  245.         If SplitPt1 < Last then QuickSort  (SplitPt1, Last);
  246.         If First < SplitPt2 then QuickSort (First, SplitPt2);
  247.       End;
  248. end;
  249. {QuickSortZ}
  250. Begin
  251.  { Calculate CenterZ coor. for each face }
  252.    For Cnt :=0 to NumPoints do
  253.      Faces2qS [Cnt,4]:= (Points2qS[Faces2qS[Cnt,1],3]+
  254.                          Points2qS[Faces2qS[Cnt,2],3]+
  255.                          Points2qS[Faces2qS[Cnt,3],3]) div 3;
  256.  { reOrder it QUICKLY!!!! }
  257.    QuickSort (0,NumPoints);
  258. End;
  259. BEGIN
  260.   MakeCosTable;
  261. END.