home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / asm / 3dvect25 / 3d.doc next >
Encoding:
Text File  |  1993-08-29  |  16.0 KB  |  275 lines

  1.     3d Vectors Source
  2.  
  3.      by John McCarthy (with a little help from his mommy)
  4.         1316 Redwood Lane
  5.         Pickering, Ontario, Canada
  6.         L1X 1C5
  7.  
  8.        (416) 831-1944 (voice, always willing to talk, but do not call at 2am)
  9.  
  10.     documentation is in  no  defined  order. sorry, i just  sorta  lumped  my
  11.     ideas together and ended up with this file.
  12.  
  13.     routines support any  x mode, - but  page  flipping  is  not  allowed  in
  14.     resolutons which allow only 1 page - see "pages" constant.
  15.  
  16.     full clipping is  performed  to  user  defind  areas - see  constants  in
  17.     equ.inc. they have   been   changed  to  memory  locations  for  variable
  18.     windowing or multiple screens.  for  windowing,  the last z locations for
  19.     that window must be remembered along with a slew of other  locations, see
  20.     vars.inc for that  info.  to change a window, save the lastz information,
  21.     reset with old lastz information and  then  call  set_clip  to change the
  22.     border clipping and screen center data.
  23.  
  24.     the theoretical screen  is  considered  to be (x,y) with  0,0  being  the
  25.     center of the  screen!.   so  -100,-100  is  somewhere  on  the top left!
  26.     actual screen goes from (0,0) to (320,200)  -  or  whatever mode size you
  27.     select.  Matt Pritchard's routines (xmode.asm) assume  0,0  to be the top
  28.     left of the  screen  while  my routines (me = John = 3d.asm) consider the
  29.     screen center to be the constants xcenter and ycenter.
  30.  
  31.     visible space is  -4628196  to +4628196  on  all  axis  (approx).  object
  32.     locations are 32 bit, vector routines are 16 bit, objects must be smaller
  33.     than 16 bit but are visable within about a 32 bit range.   (4 million, as
  34.     it is now,  is  very  very  far).   since the camera is always at (0,0,0)
  35.     (relative), objects with (relative) negative z values are not seen.  this
  36.     cuts the z space to 0 to 4mil.  visible space is always divided by 256 so
  37.     decimals can be allowed in adding, and  moving of objects.  visible space
  38.     therefore, is actually  from -1.024 billion to +1.024  billion  with  the
  39.     lower byte having  no effect on the location.  non-visible space is where
  40.     objects can be but won't appear on screen.   this space is a 256 *256*256
  41.     cube.  to racap:  you have 32 bit x,y,z axis with a visual  range  of  28
  42.     bits, where the  lower  8  bits don't affect the location.  (lower 8 bits
  43.     don't count because locations are shr'ed)   i  say that the visable space
  44.     is "about" 4mil only because of the code in the make3d routine: this code
  45.     multiplies by a  constant  and then performs divide by  z  distance.   we
  46.     cannot allow the  multiply  to  overflow  and  therfore must truncate our
  47.     maximum distance to prevent this.  the  constants  for multiplication are
  48.     the screen ratio constants and the calculation to test for an overflow is
  49.     as such -2^32/2/256/(largest constant).  the constant I  have used is 464
  50.     for the y  ratio.   I  have  used  this  because  of my desire to use the
  51.     320x400 mode resolution.  therfore, 4.3gig/2/256/464  = about 4 million -
  52.     our maximum visual  distance.  like, trust me, you don't  really  need  a
  53.     larger universe.  fixing  the  make  3d  routine  wont  allow  you to see
  54.     farther because then you would have to fix the rotate routine, etc, etc.
  55.  
  56.      when defining a location: ebx = x, ecx = y, ebp = z
  57.      when defining a rotation: x = pitch, y = heading, z = yaw
  58.      si refers to object number, di refers to time.
  59.  
  60.      rotations occure in order:
  61.      zobject,xobject,yobject,ycamera,xcamera,zcamera    -    rotations    are
  62.      compounded in matrix for faster computation.
  63.  
  64.      vmatrix is the matrix for object rotation.  ematrix is  the  matrix  for
  65.      camera rotation.   if  you want know where a point in space will show up
  66.      on the screen, load ebx, ecx, ebp with your x,y,z point, subtract camera
  67.      location and  call erotate (eye rotate).   the  point  will  be  rotated
  68.      according to current camera angles.  make sure that a call to setsincose
  69.      has taken place to set the eye rotation matrix (ematrix).
  70.  
  71.      polygon can handle any number of sides.  to draw a triangle,  make  last
  72.      point equal  to first point, eg 1,4,5,1. number of sides of a polygon is
  73.      determined so that the polygon is  not  finished  until  the  last  side
  74.      equals the first side:  eg 1,7,6,14,13,4,2,1 would be a 7 sided polygon.
  75.      the constant maxsurfaces determines that maximum number  of  surfaces an
  76.      object can have.  the constant maxpolys determines the maximum number of
  77.      connections a surface can have.
  78.  
  79.      sample shape data:
  80.  
  81.      thing  dw 6        ; number of points
  82.             dw 4        ; number of surfaces
  83.  
  84.             dw x,y,z    ; point 0
  85.             dw x,y,z    ; point 1
  86.             dw x,y,z
  87.             ...
  88.  
  89.             dw 0,1,2,3,0,  col,com  ;  surface  from  point  0-1,1-2,2-3,3-0,
  90.                                     colour and command byte
  91.             dw 2,4,1,2  , col,com ; triangle  from  points  241,  and command
  92.                                     byte
  93.             dw 2,7,2    , col,com ; line from 2 to 7
  94.             dw 6,5,9,13,25,23,1,24,14,29,12,6, col,com ; multi-sided polygon
  95.             ...
  96.  
  97.     there are several commands one can use for each surface.   commands  like
  98.     steel texture, always  visable,  opposite colours, etc.  view the objects
  99.     include file to see what/how to use them.
  100.  
  101.     bitmaps can be part of an object or be  made as seperate objects.  i will
  102.     be using the  bitmaps  for  things like explosions, smoke  (from  damaged
  103.     planes/spaceships) and distant suns/solar system (u know, like in x-wing)
  104.     set the values  bitx  and  bity to the scaling to be used for each bitmap
  105.     and set userotate  to 2 as this is  the  command  to  define  a  bitmaped
  106.     object.  vxs and  vys  are  the  additional scaling used  for  individual
  107.     objects (vxs+bitx = final scaling factor).  when part of and object, use
  108.     dw 32 (bitmap), point #, x scale, y scale.  remember, scaling is added to
  109.     bitx and bity so objects have a base scale plus some individual scale.
  110.  
  111.     complex objects don't  cut it for speed! keep your objects simple and you
  112.     can have more of them on screen at once!  maximum speed is found with low
  113.     resolutions.  high resolutions with clipped borders also provide adaquate
  114.     speed.  a shallow but wide screen (small  y, big x) provides better usage
  115.     of cpu time  than a tall and thin screen.  one big object  is  faster  to
  116.     compute than many  small  objects (if same surface area) an object viewed
  117.     from the  side takes signifiganly less  time  to  compute  than if viewed
  118.     from the top due to the shallow y, large x idea. small  option  has  been
  119.     added for objects  farther  than  smalldist distance.  object shapes have
  120.     abcd prefixes.  therefore,  as object  gets  farther  from  camera,  less
  121.     points/surface must be calculated.  you must define four shapes for every
  122.     shape.  hi-res shape is a, and lo-res shape is d.
  123.        eg dd offset athing,offset bthing, offset cthing, offset dthing
  124.  
  125.     surface data must be entered clockwize so side  will be visible.  counter
  126.     clockwize surfaces are visable from other side and will  not  be  plotted
  127.     (unless you use a surface command override, see objects.inc)
  128.  
  129.     an increase in  screen objects increases cpu time.  however, if you  know
  130.     that you will always have the screen  filled  (in the case of floors, and
  131.     runways.) you can disable the clear_fill routine during  those  parts! if
  132.     the screen will  be  covered  with background walls and such, there is no
  133.     purpose to call the clear routine  to  compute  the  next  part!   i have
  134.     therefore added a  flag  for  the clear_fill routine to  use:  when  your
  135.     animation comes to the part when your looking at the ground or walls (and
  136.     there are NO  empty  spaces)  toggle  the flag to skip clear_fill and get
  137.     more  cpu  time.  this also works if  you  are  approaching  an object or
  138.     large surface, since the new object will totaly cover  the  previous one.
  139.     another time trick is to have your main background object include the sky
  140.     (or area to  be cleared) as part of the object.  if you are going to have
  141.     walls that go  halfway up the screen,  have  them  go  halfway  with  the
  142.     regular walls and then make another surface that goes to the top of the
  143.     screen (or above if you want to move around) with the colour  0.  you can
  144.     then deactivate the  clear_fill  routine  and  still  have  the animation
  145.     appear as if the walls are completely seperate objects.
  146.  
  147.     sorting routine for objects (as opposed  to  sides)  uses last z value to
  148.     re-sort for the  next plot.  if you plan on drawing static  pictures  you
  149.     may want to  call  makobjs twice to: 1) draw and find zeds, sort, then 2)
  150.     re-draw. this will be the only way (and  easiest way) to plot an accurate
  151.     picture of what  we  have.  don't  worry  about  calling   twice   during
  152.     animations as the  first  picture  will  be  the only picture that is not
  153.     sorted.  during animations, all objects  are  sorted  properly,  based on
  154.     previous z.
  155.  
  156.     routines which are expected to be used in animations have  been optimized
  157.     but routines intended  for  use as background and title draw routines are
  158.     not intended to be fast.  if you find  any  areas  that  can be optimized
  159.     please let me know or send me your changes.  what i really  want  to know
  160.     is if the  theory  can  be  optimized!   if  i am loosing a cycle here or
  161.     there, so what.  but if i am loosing  thousands  due  to  lack of initial
  162.     insight,now i really want to know! if you send me your changes on a disk,
  163.     i will make  sure  you get your disk back with a tonne  (metric)  of  new
  164.     assembler routines.
  165.  
  166.      PLEASE DOCUMENT YOUR CHANGES!!
  167.  
  168.     newfollow routine does  not  handle  object  lock  on  well  if object is
  169.     accelerating.  the routine calculates  where  the  object  will  be in di
  170.     frames and attempts to point the camera to it in di frames.   however, if
  171.     the object is  accelerating,  then  the  object  will not be where it was
  172.     expected to be  at that time.  so the  camera  must  re-lock  on  to  its
  173.     target.  this loop commences until the camera actually  has  locked on to
  174.     the target object,  from this point on, the camera will follow the object
  175.     regardless of motion.  the re-lock on  sequence  takes the last number of
  176.     frames and divides it by two, so the re-lock on loop will move toward the
  177.     accelerating object at an accelerating rate.
  178.  
  179.     general overview: locations  are  32 bit -2.1Gig to +2.1Gig,  angles  are
  180.     16bit from 0-65535 degrees, 4 quadrants - 4096 entries each quadrant.
  181.  
  182.     variables in vector  routine  are  16bit.  cosine and sine list are words
  183.     but get converted into doublewords when used.
  184.  
  185.      some routines: (not all, just some)
  186.  
  187.      arctan        +/*% arctan(rise/run)=arctan(cx/ax).  any quadrant, 16bit
  188.      checkfront    +/*% check if points (di,bp) (si,ds) (dx,es) are clockwize
  189.      clear_fill    +/   clears write page using xupdate and yupdate variables
  190.      compound      + *% compounds angles  of  eye  and  angles of object into
  191.                         matrix
  192.      cosine        +/*% eax=cos(eax), 16bit input, 32bit output
  193.      erotate       +/*% rotate for angles of eye, 32bit, uses ematrix
  194.      fakedraw      +/   draw line in firstbyte and lastbyte  tables  from xy1
  195.                         to xy2
  196.      flip_page     +/   flip between pages 0 and 1, wait for vertical sync
  197.      drawvect      +    draw list of vectors using points, sides and order
  198.      initfont     #     initialize font pointers
  199.      initpages    #     initialize x-mode pages for flip_page to page 0
  200.      loadpoints    + *% load points into array, rotate and translate as we go
  201.      loadsurfs     + *  load surfaces, check if visible as we go
  202.      look_at_it    +/*   immediatly  force  eyeax,  eyeay  to  look at object
  203.                         wherelook
  204.      make1obj      + *  make object si
  205.      make3d        +/*% make bx,cx,bp into bx,cx 2d pair, 16bit
  206.      makeobjs      +    make all objects then sorts based on last z location
  207.      move_to      # /*  move object si to bx,cx,bp - time di frames
  208.      newfollow    # /*  forces camera to  follow object si, time to get there
  209.                         di
  210.      poly_fill     +/   uses oney,firstbyte and lastbyte to draw one surface
  211.      put_at_top     /   put eax at top of screen in box (for debugging)
  212.      re_sort       +    sorts objects based on "finalzed" values
  213.      rotate        +/*% rotate bx,cx,bp (x,y,z) through matrix vrotate, 16bit
  214.      setmakeorder #     resets order for makeobjs - for initialization
  215.      setsincose    +/   set sin and cos multipliers for eye rotations
  216.      setupbase    #     set up object base pointers to shapes
  217.      sine          +/*% ax=sin(ax), 16bit input, 32bit output
  218.      sort_list     +    sorts list of sides of polygon
  219.      updvectors    +/   updates vector xyz's, angles
  220.  
  221.      legend:
  222.  
  223.        # used for initialization of code or new scene
  224.        + used regularly in animation loop
  225.        / can be used by user outside of animation loop if needed
  226.        * routine requires parameters passed in registers
  227.        % routine exits with results in registers
  228.        > routine wipes harddrive
  229.  
  230.     there are more routines at the end of 3d.asm for more  general  functions
  231.     like find the  camera displacement and finding rotational offsets between
  232.     two objects.  u figure them out - fairly self explanatory.
  233.  
  234.     divide overflows are generally caused  by  having  an  object  behind the
  235.     screen (or too close and trying to calculate where it  is  on the screen.
  236.     obviously this cannot  be  calculated  (since  is it off the screen) when
  237.     this happens, ztruncate takes over in  make3d  routine.   minz is set  to
  238.     more than the maximum distance any point on an object  can  be  from  its
  239.     center of gravity.   use  ztruncate  to truncate underflow of z to higher
  240.     values to prevent overflows due to  the  object  being  too  wide for the
  241.     camera.  increasing the zmin value prevents object from  coming too close
  242.     to the screen.   however,  large  objects  (like  battlecruisers, landing
  243.     strips) must be  allowed to come close,  as  the  camera  pans  over  the
  244.     object, in this case, zmin is low but ztruncate takes over  to "warp" the
  245.     object to an  appropiate  on  screen  location.  ztruncate used in make3d
  246.     routine does not provide a true rendition  of  what  a  very-close object
  247.     would look like but it's fast and simple.  generally, these values do not
  248.     need to be changed unless close objects appear flat or  objects disappear
  249.     when they become  too  close.   objects  disappear  when they move to the
  250.     other side of the camera.
  251.  
  252.     draw_vect routine has a seperate routine for drawing lines (as opposed to
  253.     surfaces).  the fake_line routine and  poly_fill routine could do the job
  254.     but they were too slow.  the line was drawn twice then filled just like a
  255.     polygon but now a seperate routine clipps and draws.   you  will not need
  256.     to use this  line  drawing routine but if you want, it could be seperated
  257.     from the draw_vect routine.  I do not  use  the  xmode  line draw by Matt
  258.     Pritchard as it does not allow for clipping.
  259.  
  260.     sin and cosin tables - 90 degrees is now 16384, 180=32768...
  261.  
  262.     move_si routine - to move an object around, load up ebx, ecx and ebp with
  263.     the x,y,z locations of where you want the object to end up.  load di with
  264.     the time you would like the object to take to get there. load si with the
  265.     object number you want to move and call move_si.  the updvectors  routine
  266.     does the rest!
  267.  
  268.     to look at  an  object.  either 1) put the object number in wherelook. or
  269.     2) load si with the object to look at,  load di with the time to move the
  270.     camera to the object, and call new_follow.
  271.  
  272.     just think, only  4  months  ago (march '93), i had trouble programming a
  273.     batch file!
  274.  
  275.