home *** CD-ROM | disk | FTP | other *** search
- { 3D library }
- { Solo Programadores ver. 1.0 }
- { }
- { Some things about this library: }
- { * 360 degrees are 1024 values then 90ยบ are 255 values }
- { * Angle3D define a circle with 1024 values }
- { * SinData are stored in 8 fixed point ;) }
- { }
- { by Crom / Spanish Lords Feb 96 }
- Unit Lib3D_v2;
- INTERFACE
- Const
- { 3D origin }
- XOrg : Integer = 0;
- YOrg : Integer = 0;
- ZOrg : Integer = 60;
- { Center screen }
- XCenter : Integer = 160;
- YCenter : Integer = 100;
- { Number of points in CosTable }
- NumSinVal = 256*4;
-
- Type
- Point3D = Array [1..3] of Integer;
- Face3D = Array [1..4] of Integer;
-
- Var
- { About CosTable array: }
- { * Values are stores * 255 = 8 bits }
- { * Circle is defined in 1024 incs. }
- { then 90 degrees are 256 values ;) }
- CosTable : Array [0..NumSinVal] of Integer;
-
- FUNCTION FastSin (Angle3D:Integer):Integer;
- FUNCTION FastCos (Angle3D:Integer):Integer;
- PROCEDURE Calc3DRotations (SinX,CosX,SinY,CosY,SinZ,CosZ:Integer;
- OrgPoints : Array of Point3D;
- Var DesPoints : Array of Point3D;
- NumPoints : Word );
- PROCEDURE Proyect (XScreen, YScreen : Integer; NumPoints : Word;
- OrgPoints : Array of Point3D;
- Var DesPoints : Array of Point3D);
- FUNCTION Visible (X1,Y1,X2,Y2,X3,Y3:Integer):Boolean;
- PROCEDURE QuickSortZ (NumPoints : Word;
- Points2qS : Array of Point3D;
- Var Faces2qS : Array of Face3D);
-
- IMPLEMENTATION
- Procedure MakeCosTable;
- Var
- CntVal : Word;
- CntAng : Real;
- IncDeg : Real;
- Begin
- IncDeg := 2*PI/NumSinVal;
- CntAng := IncDeg;
- CntVal := 0;
- Repeat
- CosTable [CntVal] := Round(255*cos(CntAng));
- CntAng := CntAng+IncDeg;
- Inc (CntVal);
- Until CntVal>1024;
- End;
-
- Function FastSin (Angle3D:Integer):Integer;Assembler;
- Asm
- mov ax,Seg CosTable
- mov es,ax
- mov di,Offset CosTable
- mov dx,Angle3D
- mov bx,1024
- add dx,256
- cmp dx,bx
- jle @@Ok
- sub dx,1024
- @@Ok:
- shl dx,1
- add di,dx
- mov ax,es:[di]
- End;
-
- Function FastCos (Angle3D:Integer):Integer;assembler;
- Asm
- mov ax,Seg CosTable
- mov es,ax
- mov di,Offset CosTable
- mov dx,Angle3D
- shl dx,1
- add di,dx
- mov ax,es:[di]
- End;
-
- Procedure Calc3DRotations (SinX,CosX,SinY,CosY,SinZ,CosZ:Integer;
- OrgPoints : Array of Point3D;
- Var DesPoints : Array of Point3D;
- NumPoints : Word );
- Var
- X1,Y1,Z1 : Integer;
- Aux1,Aux2 : Integer;
- CntPoints : Word;
- Begin
- For CntPoints:=0 to NumPoints do
- Begin
- { X1 := (cos(YAngle) * X - sin(YAngle) * Z);}
- Aux1 := CosY*OrgPoints [CntPoints,1];
- Aux2 := SinY*OrgPoints [CntPoints,3];
- Asm
- mov ax,Aux1;sar ax,8;mov Aux1,ax
- mov ax,Aux2;sar ax,8;mov Aux2,ax
- End;
- X1 := Aux1-Aux2;
- { Z1 := (sin(YAngle) * X + cos(YAngle) * Z);}
- Aux1 := SinY*OrgPoints [CntPoints,1];
- Aux2 := CosY*OrgPoints [CntPoints,3];
- Asm
- mov ax,Aux1;sar ax,8;mov Aux1,ax
- mov ax,Aux2;sar ax,8;mov Aux2,ax
- End;
- Z1 := Aux1 + Aux2;
- { X := (cos(ZAngle) * X1 + sin(ZAngle) * Y);}
- Aux1 := CosZ*X1;
- Aux2 := SinZ*OrgPoints [CntPoints,2];
- Asm
- mov ax,Aux1;sar ax,8;mov Aux1,ax
- mov ax,Aux2;sar ax,8;mov Aux2,ax
- End;
- DesPoints [CntPoints,1] := Aux1 + Aux2;
- { Y1 := (cos(ZAngle) * Y - sin(ZAngle) * X1);}
- Aux1 := CosZ*OrgPoints [CntPoints,2];
- Aux2 := SinZ*X1;
- Asm
- mov ax,Aux1;sar ax,8;mov Aux1,ax
- mov ax,Aux2;sar ax,8;mov Aux2,ax
- End;
- Y1 := Aux1 - Aux2;
- { Z := (cos(XAngle) * Z1 - sin(XAngle) * Y1);}
- Aux1 := CosX*Z1;
- Aux2 := SinX*Y1;
- Asm
- mov ax,Aux1;sar ax,8;mov Aux1,ax
- mov ax,Aux2;sar ax,8;mov Aux2,ax
- End;
- DesPoints [CntPoints,3] := Aux1 - Aux2;
- { Y := (sin(XAngle)) * Z1 + cos(XAngle) * Y1);}
- Aux1 := SinX*Z1;
- Aux2 := CosX*Y1;
- Asm
- mov ax,Aux1;sar ax,8;mov Aux1,ax
- mov ax,Aux2;sar ax,8;mov Aux2,ax
- End;
- DesPoints [CntPoints,2] := Aux1 + Aux2;
- End;
- End;
-
- Procedure Proyect (XScreen, YScreen : Integer; NumPoints : Word;
- OrgPoints : Array of Point3D;
- Var DesPoints : Array of Point3D);
- Var
- CntPoints: Word;
- Begin
- For CntPoints:=0 to NumPoints do
- Begin
- { Clipping in Z ;}
- If OrgPoints[CntPoints,3]>=Zorg then
- Begin
- { What happen if point are behind me? }
- DesPoints [CntPoints,1]:=320;
- DesPoints [CntPoints,2]:=200;
- End
- else
- Begin
- DesPoints [CntPoints,1]:=
- XScreen+((XOrg*OrgPoints[CntPoints,3]-OrgPoints[CntPoints,1]*ZOrg)div(OrgPoints[CntPoints,3]-ZOrg));
- DesPoints [CntPoints,2]:=
- YScreen+((YOrg*OrgPoints[CntPoints,3]-OrgPoints[CntPoints,2]*ZOrg)div(OrgPoints[CntPoints,3]-ZOrg));
- End;
- End;
- End;
- { Comprueba si la coordenada z del vector normal al plano definido }
- { por (X1,Y1,Z1),(X2,Y2,Z2),(X3,Y3,Z3) ses positiva o no. }
- { OJO!!! Se definen los puntos de los planos que se ven en el sentido }
- { de las agujas del reloj. }
- { <rom / Slords Sep 94 }
- Function Visible (X1,Y1,X2,Y2,X3,Y3:Integer):Boolean;assembler;
- Asm
- mov cx,X2 { reg dx = (X2-X1)*(Y3-Y1)) }
- mov bx,X1
- sub cx,bx
- mov ax,Y3
- mov bx,Y1
- sub ax,bx
- imul cx
- mov dx,ax
- push dx
- mov cx,X3 { reg ax = (X3-X1)*(Y2-Y1) }
- mov bx,X1
- sub cx,bx
- mov ax,Y2
- mov bx,Y1
- sub ax,bx
- imul cx
- pop dx
- sub dx,ax { reg dx =(X2-X1)*(Y3-Y1)-(X3-X1)*(Y2-Y1) }
- js @@InVisible { Si el resultado de la resta es negativo Invisible,}
- mov ax,01
- jmp @@Fin
- @@InVisible:
- xor ax,ax
- @@Fin:
- End;
-
- Procedure QuickSortZ (NumPoints:Word;Points2qS:Array of Point3D;Var Faces2qS:Array of Face3D);
- Var
- Cnt : Word;
- { Specific sort }
- Procedure QSort (First, Last: Integer; Var Split1: Integer; Var Split2: Integer);
- Var
- AuxFace : Face3D;
- ZVal : Integer;
- Begin
- ZVal := Faces2qS[(First+Last) shr 1,4];
- Repeat
- While Faces2qS[First,4] < ZVal do Inc (First);
- While Faces2qS[Last,4] > ZVal do Dec (Last );
- If First <= Last then
- Begin
- AuxFace := Faces2qS[First];
- Faces2qS[First] := Faces2qS[Last];
- Faces2qS[Last] := AuxFace;
- Inc (First);
- Dec (Last);
- End;
- Until First > Last;
- Split1 := First;
- Split2 := Last;
- End;
- { Generic QuickSort }
- Procedure QuickSort (First, Last:Integer);
- Var
- SplitPt1, SplitPt2: Integer;
- Begin
- If First < Last then
- Begin
- qSort (First, Last, SplitPt1, SplitPt2);
- If SplitPt1 < Last then QuickSort (SplitPt1, Last);
- If First < SplitPt2 then QuickSort (First, SplitPt2);
- End;
- end;
- {QuickSortZ}
- Begin
- { Calculate CenterZ coor. for each face }
- For Cnt :=0 to NumPoints do
- Faces2qS [Cnt,4]:= (Points2qS[Faces2qS[Cnt,1],3]+
- Points2qS[Faces2qS[Cnt,2],3]+
- Points2qS[Faces2qS[Cnt,3],3]) div 3;
- { reOrder it QUICKLY!!!! }
- QuickSort (0,NumPoints);
- End;
- BEGIN
- MakeCosTable;
- END.