{ Hello Folks! Here is some 3D-Roation stuff. Tell me, what you think of it, please! --------------------------------------------------------------------- } Uses Crt,dos; (******************************************************************* * Displaying a 3D-Cube of point from any difference in any angle. * * THIS CODE IS PUBLIC DOMAIN! * * * * Writen by Axel Plinge * * Fido Net: Axel Plinge @ 2:2448/327.11 * * InterNet: axel.plinge@tca-os.ruhr.de * *******************************************************************) Type Mat33 = Array[1..3,1..3] of longint; Point2D = Record X,Y : LongInt End; Point3D = Record X,Y,Z : LongInt End; const CharLength = 8; CharSetNr = 3; Type OneChar = Array [0..CharLength-1] of Byte; TYPE ZDEF = ARRAY[#0..#255] OF onechar; ZPtr = ^ZDEF; CONST BIOS_Font : ZPtr = NIL; const RS = 40; VAR vio_seg : Word; page : Byte; Ofstab : ARRAY[0..399] OF Word; PROCEDURE Init;ASSEMBLER; ASM MOV AX,0EH INT 10h MOV DX,3d4h MOV AL,9 OUT DX,AL INC DX IN AL,DX AND AL,01110000b OUT DX,AL MOV vio_seg,0a000h MOV page,0 XOR AX,AX MOV DI,offset Ofstab PUSH DS POP ES MOV CX,400 @L: STOSW ADD AX,80 LOOP @L END; PROCEDURE flip;ASSEMBLER; ASM XOR BX,BX CMP page,0 JE @s0 MOV BX, 7d0h @s0: ADD BX,0a000h MOV vio_seg,BX XOR BX,BX CMP page,1 JE @s1 MOV BX, 7d00h MOV page,1 jmp @w @s1: MOV page,0 @w: MOV DX, 3d4h MOV AL, 0DH CLI OUT DX, AL INC DX MOV AL, BL OUT DX, AL DEC DX MOV AL, 0CH OUT DX, AL INC DX MOV AL, BH OUT DX, AL STI END; VAR Color:Byte; PROCEDURE SetzPixel(X,y:Word);ASSEMBLER; ASM MOV BX,y ADD BX,BX MOV AX,[offset Ofstab+BX] MOV BX,X MOV CL,BL shr BX,3 ADD BX,AX AND CL,7 XOR CL,7 MOV AH,1 shl AH,CL MOV DX,3ceh MOV AL,8 OUT DX,AX MOV AX,(02h shl 8) + 5 OUT DX,AX MOV AX,vio_seg MOV ES,AX MOV AL,ES:[BX] MOV AL,color MOV ES:[BX],AL END; PROCEDURE PutLine(X,y:Word;L:byte);ASSEMBLER; ASM MOV BX,y ADD BX,BX MOV AX,[offset Ofstab+BX] MOV BX,X ADD BX,AX MOV AH,L MOV DX,3ceh MOV AL,8 OUT DX,AX MOV AX,(02h SHL 8) + 5 OUT DX,AX MOV AX,vio_seg MOV ES,AX MOV AL,ES:[BX] MOV AL,Color MOV ES:[BX],AL END; PROCEDURE cls;assembler; ASM MOV DX,3ceh mov ah,0ffh MOV AL,8 OUT DX,AX MOV AX,(02h SHL 8) + 5 OUT DX,AX MOV AX,vio_seg MOV ES,AX xor bx,bx MOV cx,640*400/16 @l: MOV Ax,ES:[BX] xor Ax,ax MOV ES:[BX],Ax inc bx inc bx dec cx jnz @l END; PROCEDURE Retrace;assembler; asm MOV DX, 3dah @WaitNotVSyncLoop: in al, dx and al, 8 jnz @WaitNotVSyncLoop @WaitVSyncLoop: in al, dx and al, 8 jz @WaitVSyncLoop end; Procedure GetChars; VAR Regs:Registers; BEGIN Regs.AH:=$11; Regs.AL:=$30; Regs.BH:= CharSetNr; Intr($10,Regs); BIOS_Font:=Ptr(Regs.ES,Regs.BP); END; PROCEDURE WriteChr(X,Y:Integer;Z:Char); var I,c,Maske : Byte; BEGIN FOR i:=0 TO charLength-1 DO BEGIN PutLine(X SHR 3,y+i,BIOS_Font^[Z,I]); END; END; PROCEDURE WriteStr(X,Y:Integer;S:String); VAR I:Byte; BEGIN FOR I:=1 TO Length(S) DO BEGIN WriteChr(X,Y,S[I]); Inc(X,8); END; END; PROCEDURE WriteNr(X,Y:Integer;L:Longint); VAR I:Byte; S:String[8]; BEGIN Str(L:3,S); FOR I:=1 TO Length(S) DO BEGIN WriteChr(X,Y,S[I]); Inc(X,8); END; END; Var x, y, z : Real; i,j,k : INTEGER; tz : longint; Mat : Mat33; Dist_X, Dist_Y, Dist_Z : Integer; Ang_X, Ang_Y, Ang_Z : word; Ende : Boolean; Point : Point3d; px,py : integer; BEGIN GetChars; Init; Dist_X:=0; Dist_Y:=0; Dist_Z:=1; Ang_X:=0; Ang_Y:=0; Ang_Z:=0; Ende:=False; Repeat { Tastaturbehandlung } If KeyPressed then Begin case ReadKey of '+' : IF Dist_Z> 1 THEN DEC(Dist_Z); '-' : IF Dist_Z< 70 THEN Inc(Dist_Z); '4' : IF Dist_X>-99 THEN DEC(Dist_X); '6' : IF Dist_X< 99 THEN Inc(Dist_X); '8' : IF Dist_Y>-99 THEN DEC(Dist_Y); '2' : IF Dist_Y< 99 THEN Inc(Dist_Y); #27 : Ende:=true; #0 : CASE readkey of #77 : Ang_Y:=Ang_Y + 1; #75 : if (Ang_Y > 0) then Ang_Y:=Ang_Y - 1 else if Ang_Y=0 THEN Ang_Y:=359; #80 : Ang_X:=Ang_X + 1; #72 : if (Ang_X > 0) then Ang_X:=Ang_X - 1 else if Ang_X=0 THEN Ang_X:=359; #81 : Ang_Z:=Ang_Z + 1; #73 : if (Ang_Z > 0) then Ang_Z:=Ang_Z - 1 else if Ang_Z=0 THEN Ang_Z:=359; end; end End; IF ang_x>=360 THEN ang_x:=ang_x-360; IF ang_y>=360 THEN ang_y:=ang_y-360; IF ang_z>=360 THEN ang_z:=ang_z-360; x:=ang_x * Pi / 180; y:=ang_y * Pi / 180; z:=ang_z * Pi / 180; { Ú ¿ ³ cosZ*cosY -cosY*sinZ sinY ³ ³ cosX*sinZ-sinY*cosZ*sinX cosZ*cosX+sinX*sinZ*sinY cosY*sinX ³ ³-sinX*sinZ-sinY*cosZ*cosX -cosZ*sinX+sinZ*sinY*cosX cosX*cosY ³ À Ù } Mat[1][1]:=round(cos(z)*cos(y)*(1 SHL 12)); Mat[1][2]:=round(-sin(z)*cos(y)*(1 SHL 12)); Mat[1][3]:=round(sin(y)*(1 SHL 12)); Mat[2][1]:=round((cos(x)*sin(z)-sin(y)*cos(z)*sin(x))*(1 SHL 12)); Mat[2][2]:=round((cos(z)*cos(x)+sin(x)*sin(z)*sin(y))*(1 SHL 12)); Mat[2][3]:=round((cos(y)*sin(x))*(1 SHL 12)); Mat[3][1]:=round((-sin(x)*sin(z)-sin(y)*cos(z)*cos(x))*(1 SHL 12)); Mat[3][2]:=round((-cos(z)*sin(x)+sin(z)*sin(y)*cos(x))*(1 SHL 12)); Mat[3][3]:=round(cos(x)*cos(y)*(1 SHL 12)); { Z-Divisor } tz:=abs(Dist_Z) + 1; flip; retrace; cls; { show Data } Color:=white; WriteStr(10,10,'X'); WriteNr( 20,10, Dist_X); WriteNr( 50,10, Ang_X); WriteStr(74,10,'ø'); WriteStr(10,20,'Y'); WriteNr( 20,20, Dist_Y); WriteNr( 50,20, Ang_Y); WriteStr(74,20,'ø'); WriteStr(10,30,'Z'); WriteNr( 20,30, Dist_Z); WriteNr( 50,30, Ang_Z); WriteStr(74,30,'ø'); { Raster } color:=white; FOR k:=-5 TO 5 DO FOR j:=-5 TO 5 DO FOR i:=-5 TO 5 DO BEGIN Point.X:=RS*I-Dist_X; Point.Y:=RS*J-Dist_Y; Point.Z:=RS*K-Dist_z; { Rotation through Matrix Multiplication } Point.X:=(Point.X*MAT[1][1] + Point.Y*MAT[1][2] + Point.Z*MAT[1][3]) div (1 shl 12); Point.Y:=(Point.X*MAT[2][1] + Point.Y*MAT[2][2] + Point.Z*MAT[2][3]) div (1 shl 12); Point.Z:=(Point.X*MAT[3][1] + Point.Y*MAT[3][2] + Point.Z*MAT[3][3]) div (1 shl 12); { 3D -> 2D } Point.x:= point.x div tz; Point.y:= point.y div tz; IF (abs(Point.x)<320) AND (abs(point.y)<200) THEN BEGIN { Did I mention this was not optimized ?? ;-) } Point.X:=Point.X+320; Point.Y:=Point.Y+200; SetzPixel(Point.x,point.y); END; END; Until Ende; textmode(lastmode); END. -------------------------------------------------------------------------- Greetings Axel --- CrossPoint v3.02 R * Origin: Pascal is nice, but ASM is fast! (2:2448/327.11) SEEN-BY: 270/101 280/1 396/1 3615/50 51 PATH: 2448/327 3000 4000 10 69 2426/2011 2001 2449/600 2433/1200 PATH: 242/42 2452/110 105/42 103 270/101 396/1 3615/50