home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / aga_software / tmap-demo / 3dclip.asm < prev    next >
Assembly Source File  |  1993-02-18  |  6KB  |  315 lines

  1. ; $$TABS=8
  2. ; simple, dumb 3d polygon clipper.
  3.  
  4.  
  5.     include    'demo.i'
  6.     include    '3d.i'
  7.  
  8.     xref    point_coder,vertex,UnClippedPolygon
  9.  
  10.  
  11. DrawClippedPolygon::
  12. ;
  13. ; input d0=orcodes,d1=andcodes
  14. ; (a0)=src poly (a1)=end poly
  15.     ONTIMER    6
  16.     move.w    #4,cliplim(a6)
  17.     lea    temp_polygon_buffer2(pc),a2
  18. reclip:
  19.     btst    #CLIPB_TOP,d0
  20.     beq.s    no_topclip
  21.     lea    intersect_top(pc),a3
  22.     moveq    #CLIPB_TOP,d3
  23.     bsr    ClipPlane
  24.     tst.w    d1    ; codes_and !=0?
  25.     beq.s    no_topclip
  26. reject_polygon:
  27.     OFFTIMER    6
  28.     rts
  29. no_topclip:
  30.     btst    #CLIPB_BOT,d0
  31.     beq.s    no_botclip
  32.     lea    intersect_bot(pc),a3
  33.     moveq    #CLIPB_BOT,d3
  34.     bsr    ClipPlane
  35.     tst.w    d1
  36.     bne.s    reject_polygon
  37. no_botclip:
  38.     btst    #CLIPB_RIGHT,d0
  39.     beq.s    no_rightclip
  40.     lea    intersect_right(pc),a3
  41.     moveq    #CLIPB_RIGHT,d3
  42.     bsr.s    ClipPlane
  43.     tst.w    d1
  44.     bne.s    reject_polygon
  45. no_rightclip:
  46.     btst    #CLIPB_LEFT,d0
  47.     beq.s    no_leftclip
  48.     lea    intersect_left(pc),a3
  49.     moveq    #CLIPB_LEFT,d3
  50.     bsr.s    ClipPlane
  51.     tst.w    d1
  52.     bne.s    reject_polygon
  53. no_leftclip:
  54.     tst.w    d0    ; any codes set?
  55.     beq.s    project_polygon
  56.     subq.w    #1,cliplim(a6)
  57.     bne.s    reclip
  58.     OFFTIMER    6
  59.     rts
  60.  
  61. project_polygon:
  62. ; now, project it and move it to vertex
  63.     ONTIMER    7
  64.     lea    vertex(a6),a2
  65.     moveq    #0,d0
  66. project_loop:
  67.     move.w    (a0)+,d4
  68.     move.w    (a0)+,d5
  69.     move.w    (a0)+,d6
  70.     lea    2(a0),a0        ; codes
  71.     muls    #(DUNGEON_WINDOW_WIDTH/2),d4
  72.     divs    d6,d4
  73.     add.w    #DUNGEON_WINDOW_WIDTH/2,d4
  74.     swap    d4
  75.     muls    #(DUNGEON_WINDOW_HEIGHT/2),d5
  76.     divs    d6,d5
  77.     add.w    #DUNGEON_WINDOW_HEIGHT/2,d5
  78.     move.w    d5,d4
  79.     move.l    d4,(a2)+
  80.     addq    #1,d0
  81.     move.l    (a0)+,(a2)+
  82.     cmp.l    a0,a1
  83.     bne.s    project_loop
  84.     OFFTIMER    7
  85.     bsr    UnClippedPolygon
  86.     rts
  87.  
  88. ClipPlane::
  89. ; ClipPlane - clip a polygon against a plane.
  90. ; input: a0=src poly a1=end poly a2=dest poly a3=clip routine d3=clip bit
  91. ; output: d0=or'd codes d1=anded codes
  92. ;     a1=new end a0,a2 swapped
  93. ; polygon format is x y z c u1 u2
  94. ; where u1 and u2 are additional parameters to be clipped
  95. ; one clipper instead of 4 for simplicity and to fit in cache.
  96.     move.l    a0,-(a7)
  97.     move.l    a2,-(a7)
  98.     moveq    #0,d0    ; orcodes=0
  99.     moveq    #-1,d1    ; andcodes=-1. only lower word valid
  100. ; now, move first to last
  101.     movem.l    (a0),d2/d4/d5/d6/d7/a4    ; 6 lwords=2 pts
  102.     movem.l    d2/d4/d5/d6/d7/a4,(a1)
  103.     lea    6*2(a1),a1
  104. clip_loop:
  105.     lea    6*2(a0),a0        ; skip initial point and handle in the wrap    
  106.     cmp.l    a0,a1
  107.     beq.s    done_clip
  108. trivial_accept_loop:
  109.     move.w    6(a0),d6        ; fetch codes
  110.     btst    d3,d6
  111.     bne.s    cur_off
  112.     move.l    (a0)+,(a2)+    ; x y
  113.     or.w    d6,d0        ; interleave writes and ops because of wait-states
  114.     move.l    (a0)+,(a2)+    ; z c
  115.     and.w    d6,d1
  116.     move.l    (a0)+,(a2)+    ; u1 u2
  117.     cmp.l    a0,a1
  118.     bne.s    trivial_accept_loop
  119. done_clip:    move.l    a2,a1        ; a1=poly+npnts
  120.     move.l    (a7)+,a0
  121.     move.l    (a7)+,a2        ; src and dest now swapped
  122.     rts
  123. cur_off:
  124. ; the current point is off.
  125. ; if the previous was on, output the point bwteen prev and cur
  126. ; if the next is on, output the point between cur and next
  127. ; the plane clip routine takes d4/d5/d6=on point, (a5)=off point, d7=offy and returns
  128. ; d4/d5/d6=intxyz, d2=t
  129.     btst    d3,-12+7(a0)    ; prv off?
  130.     bne.s    prv_was_off
  131.     movem.w    -12(a0),d4/d5/d6
  132.     move.l    a0,a5
  133.     move.w    2(a5),d7
  134.     jsr    (a3)        ; call plane clip routine
  135.     bsr    point_coder
  136.     movem.w    d4-d7,(a2)        ; output xyz
  137.     or.w    d7,d0
  138.     and.w    d7,d1
  139.     lea    8(a2),a2
  140.     move.w    8(a0),d7        ; d7=u1
  141.     move.w    -12+8(a0),d4    ; d4=u0
  142.     sub.w    d4,d7
  143.     muls    d2,d7
  144.     add.l    d7,d7
  145.     swap    d7
  146.     add.w    d4,d7
  147.     move.w    d7,(a2)+
  148.     move.w    10(a0),d7        ; d3=v1
  149.     move.w    -12+10(a0),d4    ; d4=v0
  150.     sub.w    d4,d7
  151.     muls    d2,d7
  152.     add.l    d7,d7
  153.     swap    d7
  154.     add.w    d4,d7
  155.     move.w    d7,(a2)+
  156. prv_was_off:
  157.     btst    d3,7+12(a0)        ; next off?
  158.     bne.s    clip_loop        ; next off too, so we are done
  159.     movem.w    12(a0),d4/d5/d6
  160.     move.l    a0,a5
  161.     move.w    2(a5),d7
  162.     jsr    (a3)        ; comput intersection
  163.     bsr    point_coder
  164.     movem.w    d4-d7,(a2)        ; output xyz
  165.     or.w    d7,d0
  166.     and.w    d7,d1
  167.     lea    8(a2),a2
  168.     move.w    8(a0),d7        ; d3=u1
  169.     move.w    12+8(a0),d4    ; d4=u0
  170.     sub.w    d4,d7
  171.     muls    d2,d7
  172.     add.l    d7,d7
  173.     swap    d7
  174.     add.w    d4,d7
  175.     move.w    d7,(a2)+
  176.     move.w    10(a0),d7        ; d3=v1
  177.     move.w    12+10(a0),d4    ; d4=v0
  178.     sub.w    d4,d7
  179.     muls    d2,d7
  180.     add.l    d7,d7
  181.     swap    d7
  182.     add.w    d4,d7
  183.     move.w    d7,(a2)+
  184.     bra    clip_loop
  185.  
  186. intersect_top:
  187. ; point is above z=y
  188. ; so, t=(z0-y0)/(y1-y0-z1+z0)
  189. ; out=(x1-x0)*t+x0,(y1-y0)*t+y0,y
  190. ; (a4)=x0 (a5)=x1
  191. ; ret d4/d5/d6=xyz d2=t can trash d7/a4/a5
  192.     move.w    d6,d2    ; d2=z0
  193.     sub.w    d5,d2    ; d2=z0-y0
  194.     swap    d2
  195.     clr.w    d2
  196.     asr.l    #1,d2
  197.     sub.w    d5,d6    ; d6=z0-y0
  198.     add.w    d7,d6    ; d6=y1-y0+z0
  199.     sub.w    4(a5),d6    ; d6=y1-y0-z1+z0
  200.     divs    d6,d2    ; d2=t
  201.     move.w    d4,d6    ; d6=x0
  202.     sub.w    (a5),d4
  203.     neg.w    d4    ; d4=x1-x0
  204.     muls    d2,d4
  205.     add.l    d4,d4
  206.     swap    d4    ; d4=t*(x1-x0)
  207.     add.w    d6,d4    ; d4=outx=t*(x1-x0)+x0
  208.     sub.w    d5,d7    ; d7=y1-y0
  209.     muls    d2,d7
  210.     add.l    d7,d7
  211.     swap    d7
  212.     add.w    d7,d5    ; d5=outy=t*(x1-y0)+y0
  213.     move.w    d5,d6    ; d6=outz=outy
  214.     rts
  215.  
  216. intersect_bot:
  217. ; point is below z=-y
  218. ; so, t=(z0+y0)/(y0+z0-z1-y1)
  219. ; out=(x1-x0)*t+x0,(y1-y0)*t+y0,-y
  220. ; (a4)=x0 (a5)=x1
  221. ; ret d4/d5/d6=xyz d2=t can trash d7/a4/a5
  222.     move.w    d6,d2        ; d2=z0
  223.     add.w    d5,d2        ; d2=z0+y0
  224.     swap    d2
  225.     clr.w    d2
  226.     asr.l    #1,d2
  227.     sub.w    d7,d6        ; d6=z0-y1
  228.     add.w    d5,d6        ; d6=z0-y1+y0
  229.     sub.w    4(a5),d6    ; d6=z0-y1+y0-z1
  230.     divs    d6,d2        ; d2=t
  231.     move.w    d4,d6        ; d6=x0
  232.     sub.w    (a5),d4
  233.     neg.w    d4        ; d4=x1-x0
  234.     muls    d2,d4
  235.     add.l    d4,d4
  236.     swap    d4        ; d4=t*(x1-x0)
  237.     add.w    d6,d4        ; d4=outx=t*(x1-x0)+x0
  238.     sub.w    d5,d7        ; d7=y1-y0
  239.     muls    d2,d7
  240.     add.l    d7,d7
  241.     swap    d7
  242.     add.w    d7,d5        ; d5=outy=t*(x1-y0)+y0
  243.     move.w    d5,d6    
  244.     neg.w    d6        ; d6=outz=-outy
  245.     rts
  246.  
  247. intersect_right:
  248. ; point is to the right of z=x
  249. ; so, t=(x0-z0)/(z1-x1+x0-z0)
  250. ; out=(x1-x0)*t+x0, (y1-y0)*t+y0, x
  251.     move.w    d4,d2        ; d2=x0
  252.     sub.w    d6,d2        ; d2=x0-z0
  253.     swap    d2
  254.     clr.w    d2
  255.     asr.l    #1,d2
  256.     neg.w    d6        ; d6=-z0
  257.     add.w    d4,d6        ; d6=x0-z0
  258.     sub.w    (a5),d6        ; d6=-x1+x0-z0
  259.     add.w    4(a5),d6        ; d6=z1-x1+x0-z0
  260.     divs    d6,d2        ; d2=t
  261.     move.w    d4,d6        ; d6=x0
  262.     sub.w    (a5),d4
  263.     neg.w    d4        ; d4=x1-x0
  264.     muls    d2,d4
  265.     add.l    d4,d4
  266.     swap    d4        ; d4=t*(x1-x0)
  267.     add.w    d6,d4        ; d4=outx=t*(x1-x0)+x0
  268.     sub.w    d5,d7        ; d7=y1-y0
  269.     muls    d2,d7
  270.     add.l    d7,d7
  271.     swap    d7
  272.     add.w    d7,d5        ; d5=outy=t*(y1-y0)+y0
  273.     move.w    d4,d6        ; d6=outz=x
  274.     rts
  275.     
  276. intersect_left:
  277. ; point is to the left of z=-x
  278. ; so,t=(z0+x0)/(x0+z0-z1-x1)
  279. ; out=(x1-x0)*t+x0, (y1-y0)*t+y0, -x
  280.     add    d4,d6        ; d6=z0+x0
  281.     move    d6,d2
  282.     swap    d2
  283.     clr.w    d2
  284.     asr.l    #1,d2
  285.     sub.w    (a5),d6        ; d6=z0+x0-x1
  286.     sub.w    4(a5),d6        ; d6=z0+x0-x1
  287.     divs    d6,d2        ; d2=t
  288.     move.w    d4,d6
  289.     sub.w    (a5),d4        ; x0-x1
  290.     neg.w    d4        ; x1-x0
  291.     muls    d2,d4
  292.     add.l    d4,d4
  293.     swap    d4
  294.     add.w    d6,d4        ; d4=outx
  295.     move.w    d5,d6        ; d6=y0
  296.     sub.w    d7,d5        ; y0-y1
  297.     neg.w    d5        ; y1-y0
  298.     muls    d2,d5
  299.     add.l    d5,d5
  300.     swap    d5
  301.     add.w    d6,d5
  302.     move.w    d4,d6
  303.     neg.w    d6
  304.     rts
  305.  
  306.  
  307.  
  308.  
  309.  
  310. temp_polygon_buffer2:
  311.     ds.w    6*20        ; 18 vertices max
  312.  
  313.     section    __MERGED,data
  314. cliplim::    dc.w    0
  315.