DECLARE SUB dat () DECLARE SUB pal () '3D dots cube 'Hoppy's Fab 3D Camera - Target system 'CORRECTLY (at last) shows the 3D world from any place (Camera) looking to 'any place (Target). No Pukey angles required (except for roll should it be 'desired - avoid (sideways tilt); it is GRIM) DECLARE SUB RotateX (c AS ANY) DECLARE SUB RotateY (c AS ANY) DECLARE SUB RotateZ (c AS ANY) DECLARE SUB Screen3D (c AS ANY) CLS RANDOMIZE TIMER Pi# = ATN(1) * 4 TYPE coord X AS SINGLE Y AS SINGLE Z AS SINGLE END TYPE TYPE pixel X AS INTEGER Y AS INTEGER Colour AS INTEGER END TYPE dat CLS PRINT "Escape quits" PRINT "Space Toggles Z rotation on/off" PRINT INPUT "Grid (<= 17 BUT I advise 2 for 386, 7 for 486, 12 for Pentium :", g% n% = g% ^ 3 PRINT n%; "Points. Press return" WHILE INKEY$ <> CHR$(13) WEND pal CLS DIM SHARED perspective, Rot AS coord, Pix AS pixel, PT(n%) AS pixel, p(n%) AS pixel DIM Target AS coord, Camera AS coord, Points(n%) AS coord, T(n%) AS coord perspective = 300 DIM SHARED CosX, SinX, CosY, SinY, CosZ, SinZ s = 100 / (g% - 1) start: FOR aX% = 0 TO g% - 1 FOR aY% = 0 TO g% - 1 FOR aZ% = 0 TO g% - 1 a% = a% + 1 Points(a%).X = (((g% - 1) / 2) - aX%) * s Points(a%).Y = (((g% - 1) / 2) - aY%) * s Points(a%).Z = (((g% - 1) / 2) - aZ%) * s NEXT aZ% NEXT aY% NEXT aX% top: i& = i& + 1 Camera.X = SIN(i& / 15.54) * 60 Camera.Y = COS(i& / 21.312) * 60 Camera.Z = SIN(i& / 63.45) * 300 Target.X = SIN(i& / 45.689) * 50 Target.Y = SIN(i& / 35.624) * 50 Target.Z = SIN(i& / 41.12) * 50 DX = Target.X - Camera.X: IF ABS(DX) < .01 THEN DX = .01 DY = Target.Y - Camera.Y: IF ABS(DY) < .01 THEN DY = .01 DZ = Target.Z - Camera.Z: IF ABS(DZ) < .01 THEN DZ = .01 XRot = ATN(DY / SQR(DX * DX + DZ * DZ)) IF DZ > 0 THEN YRot = ATN(DX / DZ) ELSE YRot = Pi# - ATN(DX / -DZ) END IF 'ZRot=Waste of time except for vomity tilts Zrot = Zrot + ZI i$ = INKEY$ IF i$ = CHR$(27) THEN END IF i$ = " " THEN IF ZI = .1 THEN ZI = 0 ELSE ZI = .1 CosX = COS(XRot): SinX = SIN(XRot) CosY = COS(YRot): SinY = SIN(YRot) CosZ = COS(Zrot): SinZ = SIN(Zrot) FOR a% = 1 TO n% T(a%).X = Points(a%).X - Camera.X T(a%).Y = Points(a%).Y - Camera.Y T(a%).Z = Points(a%).Z - Camera.Z RotateY T(a%): T(a%) = Rot RotateX T(a%): T(a%) = Rot RotateZ T(a%) PT(a%) = p(a%) Screen3D Rot p(a%) = Pix IF Pix.Colour < 0 THEN p(a%).Colour = 0 NEXT a% FOR a% = 1 TO n% PSET (PT(a%).X, PT(a%).Y), 0 PSET (p(a%).X, p(a%).Y), p(a%).Colour NEXT a% GOTO top SUB dat PRINT "Sorry if you were expecting turbo warp speed rotation, but the 3D bit" PRINT "Has now been corrected (The old one as in Wibble, Dotsy, Stars etc was buggered" PRINT "And had some major bugs in it (3D type bugs! Whoops), so I have started again." PRINT "Note that the types, subs etc slow it down very much (but I used them since" PRINT "it is now possible to understand my program.))" PRINT "The new 3D bit is much improved, and includes REAL perspective, depending on" PRINT "distance, not some weird thing 'like' distance. Also it now uses a totaly" PRINT "New idea of 'Camera - Target' which is where you specify the camera x,y,z" PRINT "and target x,y,z. This is a MUCH easier system to use for 3D, but unfortunately" PRINT "slower (than the last one, which used pseudo distance (hardly distance at all" PRINT "really!) and various 3D angle type things." PRINT "The various subs take the camera and target location, and calculate the position" PRINT "of every single point in your defined 3D world (a 'dot cube' in this one)" PRINT "This involves working out some 3D angles, and Bizare rotations. " PRINT "There is one unused variable - ZRot," PRINT "first some 3D explanations though" PRINT PRINT "Space" SLEEP 0 CLS PRINT "In 3D there are basicly 2 things you can do which do not affect the SHAPE of an" PRINT "object : - Translate, and Rotate" PRINT "Translation is easy, but rotation is harder. There are 3 types of rotation" PRINT "Pitch - up/down (about the X axis), Yaw - left/right (about the Y axis)" PRINT "and Roll - tilting (\/ etc) (about the Z axis). Note here X is L/R, Y is" PRINT "U/D and Z is in/out of the screen. Pitch and Yaw are the most useful -" PRINT "to work out camera - target you translate, yaw, pitch as needed (this is quite" PRINT "fiddly, needing some nasty trigs). ZRot is roll, and is like putting your head" PRINT "to one side - ie not to useful for landscape drawing etc (this is not used in" PRINT "games like Doom and Heretic, and enables the code to be simplified. In Descent" PRINT "however it is used (You can roll the ship round, and make your self sick))" PRINT PRINT "There you are - 3D for dummies, explained in the typical Hoppy patronising way!" PRINT PRINT "Space" SLEEP 0 END SUB SUB pal SCREEN 13 PALETTE 255, 4144959 COLOR 255 PRINT "Paletterification currently going on!" FOR j% = 0 TO 63 PALETTE j%, j% + j% * 256 + j% * 65536 LOCATE , 1: PRINT INT(j% / 2.55); NEXT j% FOR j% = 63 TO 255 PALETTE j%, 4144959 LOCATE , 1: PRINT INT(j% / 2.55); NEXT j% END SUB SUB RotateX (c AS coord) Rot.X = c.X Rot.Y = c.Y * CosX - c.Z * SinX Rot.Z = c.Y * SinX + c.Z * CosX END SUB SUB RotateY (c AS coord) Rot.X = c.X * CosY - c.Z * SinY Rot.Y = c.Y Rot.Z = c.X * SinY + c.Z * CosY END SUB SUB RotateZ (c AS coord) Rot.X = c.X * CosZ - c.Y * SinZ Rot.Y = c.X * SinZ + c.Y * CosZ Rot.Z = c.Z END SUB SUB Screen3D (c AS coord) distance = SQR(c.X * c.X + c.Y * c.Y + c.Z * c.Z) mag = distance / perspective IF mag > .01 AND c.Z >= 0 THEN Pix.X = 160 + (c.X / mag) Pix.Y = 100 - (c.Y / mag) Pix.Colour = 3000 / distance END IF END SUB