home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
ML_3DROT.ZIP
/
SOURCES
/
ENGINE3D.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-05-04
|
5KB
|
162 lines
Unit Engine3d;
{
3D Engine, v3.01
by Maple Leaf, 1996
No fuckin rights reserved.
last update: 4th May 1996
}
Interface
Const
Perspective : Boolean = True; { Default with perspective }
ZoomFactor : LongInt = 220; { Zooming 220% as default }
PiOver180 : Real = Pi/180;
CenterX : LongInt = 160; { Center's coordinates }
CenterY : LongInt = 100;
ObserverX : LongInt = 0; { Defaults. See procedure SetObserver.. }
ObserverY : LongInt = 0;
ObserverDist : LongInt = 300; { Initial focus }
CameraX : Longint = 0; { Initial camera coords in 3D space }
CameraY : Longint = 0;
CameraZ : Longint = 0;
Var
_3DX : LongInt; {-----------}
_3DY : LongInt; { 3D coords }
_3DZ : LongInt; {-----------}
_2DX : LongInt; { 2D X }
_2DY : LongInt; { 2D Y }
{ ---- Angles ---- }
RotAngle, TiltAngle : Integer;
CosA, CosB, SinA, SinB : Real;
CosTab, SinTab : Array [0..359] of LongInt; { Integer(cosinus|sinus*256) }
Xt, Yt, Zt, TmpEqu : LongInt;
Procedure SetCenter (x,y:Integer);
{ Sets the center of the screen }
Procedure SetAngles (Rotation,Tilt:Integer);
{ Sets the angles (horizontal rotation and tilt) }
Procedure SetObserverPosition (x,y:LongInt; Focus:LongInt);
{ Sets the focus of the camera (e.g. the distance between the
observer and the projection plane), and the 2D position (X,Y)
of the observer in a plane parallel w/ the projection plane. }
Procedure SetCamera (x,y,z:Longint);
{ Sets the (X,Y,Z) position of the camera in the virtual 3D space }
{ Or else: (X,Y,Z) will be the only point which has a FIXED position
onto the 2D desktop (e.g. screen), for any rotations }
Procedure MapCoordinates;
{ Default Floating-Point mapping routine. Translates a 3D point into a 2D one. }
Procedure IntMapCoordinates;
{ Default integer-mapping routine. Translates a 3D point into a 2D one. }
Procedure IntMapCoordinates2;
{ Second integer-mapping routine. Uses ZoomFactor=256=constant, for speed. }
Procedure IncrAngle (var Angle:Integer; value:integer);
{ Increment or decrement the specified angle w/ a specified
value, taking care of translating the result in the interval [0-359] }
Implementation
{$L engine3d}
Procedure IntMapCoordinates;external;
Procedure IntMapCoordinates2;external;
Procedure SetCenter(x,y:Integer);assembler;
asm
mov ax,x
db 66h; cbw
db 66h; mov word ptr CenterX,ax { Screen center (X coordinate) }
mov ax,y
db 66h; cbw
db 66h; mov word ptr CenterY,ax { Screen center (Y coordinate) }
end;
Procedure SetAngles(Rotation,Tilt:Integer);
begin
RotAngle:=Rotation;
TiltAngle:=Tilt;
IncrAngle(RotAngle,0);
IncrAngle(TiltAngle,0);
end;
Procedure SetObserverPosition(x,y:LongInt; Focus:LongInt);assembler;
asm
db 66h; mov ax,word ptr x
db 66h; neg ax
db 66h; mov word ptr ObserverX,ax { Observer's X position }
db 66h; mov ax,word ptr y
db 66h; neg ax
db 66h; mov word ptr ObserverY,ax { Observer's Y position }
db 66h; mov ax,word ptr Focus
db 66h; mov word ptr ObserverDist,ax { Distance from the observer to the projection plane (z=0) }
end;
Procedure MapCoordinates;
var Xt,Yt,Zt : Real;
OneOverZt : Real;
begin
{ Init some vars, for speed }
CosA:=Cos( RotAngle * PiOver180 );
SinA:=Sin( RotAngle * PiOver180 );
CosB:=Cos( TiltAngle* PiOver180 );
SinB:=Sin( TiltAngle* PiOver180 );
{ Init camera (bring it to the virtual screen's center) }
_3dx:=_3dx-CameraX;
_3dy:=_3dy-CameraY;
_3dz:=_3dz-CameraZ;
{ Calculations }
Xt:= ObserverX + _3DX*CosA - _3DY*SinA;
Yt:= ObserverY + (_3DX*SinA+_3DY*CosA)*SinB + _3DZ*CosB;
if Perspective then begin
Zt:= ObserverDist + (_3DX*SinA+_3DY*CosA)*CosB - _3DZ*SinB;
_2DX:=CenterX+Trunc(Xt*ZoomFactor/Zt);
_2DY:=CenterY-Trunc(Yt*ZoomFactor/Zt*13/16);
end else begin
_2DX:=CenterX+Trunc(Xt); { Faster, but less precise in aspect - no running points }
_2DY:=CenterY-Trunc(Yt*13/16); { Faster, but less precise in aspect }
end;
end;
Procedure IncrAngle(var Angle:Integer; value:integer);assembler;
asm
les di,Angle
mov ax,value
mov cx,es:[di]
add cx,ax
or cx,cx
jl @Under
cmp cx,359
jg @Above
mov es:[di],cx
jmp @Ok
@Above:
sub cx,360
mov es:[di],cx
jmp @Ok
@Under:
mov ax,360
add ax,cx
mov es:[di],ax
@Ok:
end;
Procedure SetCamera(x,y,z:longint);assembler;
asm
db 66h; mov ax,word ptr x
db 66h; mov word ptr CameraX,ax
db 66h; mov ax,word ptr y
db 66h; mov word ptr CameraY,ax
db 66h; mov ax,word ptr z
db 66h; mov word ptr CameraZ,ax
end;
var k:word;
Begin
{ Constructing default COS and SIN tables ... }
for k:=0 to 359 do begin
CosTab[k]:=LongInt(Trunc(cos(k*pi/180)*256));
SinTab[k]:=LongInt(Trunc(sin(k*pi/180)*256));
end;
End.