home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / int3d.asm < prev    next >
Assembly Source File  |  1996-03-19  |  12KB  |  652 lines

  1.     TITLE    INT3D - OBJECT/MOVE SPPT IN ASSEMBLER
  2.  
  3.     COMMENT $
  4.  
  5.  
  6. /* Routines for moving, scaling and rotating objects */
  7. /* Matrix math, assembly by Dave Stampe */
  8. /* converted to assembly 12/12/93 by Dave Stampe */
  9.  
  10. ALL routines in this module by Dave Stampe
  11.  
  12. /*
  13.  This code is part of the VR-386 project, created by Dave Stampe.
  14.  VR-386 is a desendent of REND386, created by Dave Stampe and
  15.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  16.  Stampre for VR-386.
  17.  
  18.  Copyright (c) 1994 by Dave Stampe:
  19.  May be freely used to write software for release into the public domain
  20.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  21.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  22.  this software or source code into their products!  Usually there is no
  23.  charge for under 50-100 items for low-cost or shareware products, and terms
  24.  are reasonable.  Any royalties are used for development, so equipment is
  25.  often acceptable payment.
  26.  
  27.  ATTRIBUTION:  If you use any part of this source code or the libraries
  28.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  29.  and any other authors in your documentation, source code, and at startup
  30.  of your program.  Let's keep the freeware ball rolling!
  31.  
  32.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  33.  REND386, improving programmer access by rewriting the code and supplying
  34.  a standard API.  If you write improvements, add new functions rather
  35.  than rewriting current functions.  This will make it possible to
  36.  include you improved code in the next API release.  YOU can help advance
  37.  VR-386.  Comments on the API are welcome.
  38.  
  39.  CONTACT: dstampe@psych.toronto.edu
  40. */
  41.         $
  42.  
  43.     .MODEL large
  44.  
  45. ; # define XFSC 536870912   /* 2**29 for shifting xform coeffs to long */
  46.  
  47.  
  48.     .DATA
  49.  
  50. include 3dstruct.inc
  51.  
  52. extrn   _sqrtable    ; pointer to 8-bit precision sqrt table
  53.  
  54.     .CODE INTMATH
  55.  
  56.  
  57. MULT29     MACRO a,b                 ; multiply <3.29> -> eax
  58.     mov    eax,DWORD PTR a
  59.     imul    DWORD PTR b
  60.     shrd    eax,edx,29
  61.     adc    eax,0
  62.     ENDM
  63.  
  64. MMULT29 MACRO a,b,c               ; multiply 3 of <3.29> -> eax
  65.     mov    eax,DWORD PTR a
  66.     imul    DWORD PTR b
  67.     shrd    eax,edx,29
  68.     adc    eax,0
  69.     imul    DWORD PTR c
  70.     shrd    eax,edx,29
  71.     adc    eax,0
  72.     ENDM
  73.  
  74. DOTPROD    MACRO a,b,c,x,y,z,p      ; dot product plus p, accum in ecx:ebx
  75.     mov    eax,a            ; result in eax
  76.     imul    DWORD PTR x
  77.     mov    ecx,edx
  78.     mov    ebx,eax
  79.     mov    eax,b
  80.     imul    DWORD PTR y
  81.     add    ebx,eax
  82.     adc    ecx,edx
  83.     mov    eax,c
  84.     imul    DWORD PTR z
  85.     add    eax,ebx
  86.     adc    edx,ecx
  87.     shrd    eax,edx,29
  88.     adc    eax,p
  89.     ENDM
  90.  
  91.  
  92. ;/************ COLLISION DETECTION AND SELECTION ***********/
  93.  
  94. ;long sphere_pretest(OBJECT *obj, long x, long y, long z)
  95. ;   tests 3D selection point for best object to select */
  96. ;   returns 0x7FFFFFFF if not in obj bounds, else
  97. ;   returns abs(x1-x2) + abs(y1-y2) + abs(z1-z2)
  98. ;   <conservative closeness: always greater than actual>
  99.  
  100.  
  101. obj    equ    [bp+8]          ; arguments
  102. x    equ    [bp+12]
  103. y    equ    [bp+16]
  104. z    equ    [bp+20]
  105.  
  106. sx    equ     es:[di].O_sphx
  107. sy    equ     es:[di].O_sphy
  108. sz    equ     es:[di].O_sphz
  109. sr    equ     es:[di].O_sphr
  110.  
  111.  
  112.     PUBLIC    _sphere_pretest
  113.  
  114. _sphere_pretest    proc    far
  115.  
  116.     .386
  117.     push    ebp
  118.     mov    ebp,esp
  119.  
  120.     push    ecx
  121.     push    edi
  122.  
  123.     les    di,DWORD PTR obj    ; ptr to object
  124.  
  125.     mov    eax,sx   ;/* x bounds */
  126.     sub    eax,x
  127.     cmp    eax,sr
  128.     jg    notin
  129.     neg    eax
  130.     cmp    eax,sr
  131.     jg    notin
  132.  
  133.     mov    eax,sy   ;/* y bounds */
  134.     sub    eax,y
  135.     cmp    eax,sr
  136.     jg    notin
  137.     neg    eax
  138.     cmp    eax,sr
  139.     jg    notin
  140.  
  141.     mov    eax,sz   ;/* z bounds */
  142.     sub    eax,z
  143.     cmp    eax,sr
  144.     jg    notin
  145.     neg    eax
  146.     cmp    eax,sr
  147.     jg    notin
  148.  
  149.     imul    eax      ;/* square of distance to center */
  150.     mov    ebx,eax
  151.     mov    ecx,edx
  152.  
  153.     mov    eax,sx
  154.     sub    eax,x
  155.     imul    eax
  156.     add    ebx,eax
  157.     adc    ecx,edx
  158.  
  159.     mov    eax,sy
  160.     sub    eax,y
  161.     imul    eax
  162.     add    ebx,eax
  163.     adc    ecx,edx
  164.  
  165.     mov    eax,sr   ;/* square of radius */
  166.     imul    eax
  167.     cmp    edx,ecx
  168.     ja    in
  169.     jb    notin
  170.     cmp    eax,ebx
  171.     jae    in
  172. notin:                            ;/* outside of sphere */
  173.     mov    eax,07FFFFFFFh;      ;/* big never wins */
  174.     jmp    retlarge
  175. in:
  176. ;test    ebx,-1         ;/* shift so denom. is 32-bit or less */
  177. ;jz    nolo1
  178. ;mov    eax,edx
  179. ;xor    edx,edx
  180. ;mov    ebx,ecx
  181. ;xor    ecx,ecx
  182. ;nolo1:
  183.     mov    eax,x    ;/* abs(x-sx)+abs(y-sy)+abs(z-sz) approx. dist from center */
  184.     sub    eax,sx
  185.     cdq
  186.     xor    eax,edx
  187.     sub    eax,edx
  188.     mov    ebx,eax
  189.  
  190.     mov    eax,y
  191.     sub    eax,sy
  192.     cdq
  193.     xor    eax,edx
  194.     sub    eax,edx
  195.     add    ebx,eax
  196.  
  197.     mov    eax,z
  198.     sub    eax,sz
  199.     cdq
  200.     xor    eax,edx
  201.     sub    eax,edx
  202.     add    ebx,eax
  203.  
  204.     mov    eax,ebx
  205. retlarge:
  206.     shld    edx,eax,16    ; return in eax and dx:ax
  207.  
  208.     pop    edi
  209.     pop    ecx
  210.  
  211.     mov    esp,ebp
  212.     pop    ebp
  213.     ret
  214.  
  215. _sphere_pretest    endp
  216.  
  217.  
  218. ;/************* POLYGON NORMAL COMPUTATION *************/
  219.  
  220.  
  221. ;    /* compute, unitize (3.29 format) normal to plane.   */
  222. ;    /* returns -1 if normal is zero, else log2(length)   */
  223. ;int find_normal(long x1, long y1, long z1,
  224. ;         long x2, long y2, long z2,
  225. ;         long x3, long y3, long z3,
  226. ;         long *xn, long *yn, long *zn)
  227. ; extern int sqrtable[1024];
  228.  
  229.  
  230. x1    equ    [bp+8]          ; arguments
  231. y1    equ    [bp+12]
  232. z1    equ    [bp+16]
  233. x2    equ    [bp+20]
  234. y2    equ    [bp+24]
  235. z2    equ    [bp+28]
  236. x3    equ    [bp+32]
  237. y3    equ    [bp+36]
  238. z3    equ    [bp+40]
  239. xn    equ    [bp+44]
  240. yn    equ    [bp+48]
  241. zn    equ    [bp+52]
  242.  
  243. xh    equ    [bp-4]        ; locals
  244. xl    equ    [bp-8]
  245. yh    equ    [bp-12]
  246. yl    equ    [bp-16]
  247. zh    equ    [bp-20]
  248. zl    equ    [bp-24]
  249. xah    equ    [bp-28]
  250. xal    equ    [bp-32]
  251. yah    equ    [bp-36]
  252. yal    equ    [bp-40]
  253. zah    equ    [bp-44]
  254. zal    equ    [bp-48]
  255. length    equ    [bp-52]
  256.  
  257.     PUBLIC    _find_normal
  258.  
  259. _find_normal    proc    far
  260.  
  261.     .386
  262.     push    ebp
  263.     mov    ebp,esp
  264.     sub    esp,60
  265.  
  266.     push    esi
  267.     push    edi
  268.     push    ecx
  269.     push    edx
  270.  
  271.     mov    eax,y2        ;/* compute 64-bit cross product   */
  272.     sub    eax,y1        ;/* and also abs. value for shifts */
  273.     mov    ecx,z3
  274.     sub    ecx,z2
  275.     imul    ecx
  276.     mov    edi,edx
  277.     mov    esi,eax
  278.     mov    eax,y3
  279.     sub    eax,y2
  280.     mov    ecx,z2
  281.     sub    ecx,z1
  282.     imul    ecx
  283.     sub    esi,eax
  284.     sbb    edi,edx
  285.     mov    xh,edi
  286.     mov    xl,esi
  287.     jge    stax
  288.     not    edi
  289.     not    esi
  290.     add    esi,1
  291.     adc    edi,0
  292. stax:
  293.     mov    xah,edi
  294.     mov    xal,esi
  295.  
  296.     mov    eax,z2
  297.     sub    eax,z1
  298.     mov    ecx,x3
  299.     sub    ecx,x2
  300.     imul    ecx
  301.     mov    edi,edx
  302.     mov    esi,eax
  303.     mov    eax,z3
  304.     sub    eax,z2
  305.     mov    ecx,x2
  306.     sub    ecx,x1
  307.     imul    ecx
  308.     sub    esi,eax
  309.     sbb    edi,edx
  310.     mov    yh,edi
  311.     mov    yl,esi
  312.     jge    stay
  313.     not    edi
  314.     not    esi
  315.     add    esi,1
  316.     adc    edi,0
  317. stay:
  318.     mov    yah,edi
  319.     mov    yal,esi
  320.  
  321.     mov    eax,x2
  322.     sub    eax,x1
  323.     mov    ecx,y3
  324.     sub    ecx,y2
  325.     imul    ecx
  326.     mov    edi,edx
  327.     mov    esi,eax
  328.     mov    eax,x3
  329.     sub    eax,x2
  330.     mov    ecx,y2
  331.     sub    ecx,y1
  332.     imul    ecx
  333.     sub    esi,eax
  334.     sbb    edi,edx
  335.     mov    zh,edi
  336.     mov    zl,esi
  337.     jge    staz
  338.     not    edi
  339.     not    esi
  340.     add    esi,1
  341.     adc    edi,0
  342. staz:
  343.     mov    zah,edi
  344.     mov    zal,esi
  345.                 ;/* now normalize to 3.29 */
  346.     or    esi,yal
  347.     or    esi,xal
  348.     or    edi,yah
  349.     or    edi,xah
  350.     jz    zero_h
  351.  
  352.     xor    ax,ax           ;/* ax is shift count */
  353.     test    edi,0FFFF0000h  ;/* top word not zero: cnvt to 1.n <3.29> */
  354.     jz    z16h
  355.     add    ax,16
  356.     shr    edi,16
  357. z16h:
  358.     test    di,0FF00h
  359.     jz    z8h
  360.     add    ax,8
  361.     shr    edi,8
  362. z8h:
  363.     shl    edi,8       ;/* most ecomonical pos'n */
  364.     bsr    cx,di       ;/* get exact shift */
  365.     sub    cx,5
  366.     add     cx,ax
  367.  
  368.     mov    eax,xh      ;/* convert cross product to 1.n */
  369.     shrd    xl,eax,cl
  370.     mov    eax,yh
  371.     shrd    yl,eax,cl
  372.     mov    eax,zh
  373.     shrd    zl,eax,cl
  374.  
  375.     add    cx,29
  376.     mov    length,cx
  377.  
  378.     jmp    dshnorm
  379. zero_h:
  380.     or    esi,esi
  381.     jz    zero_normal
  382.     mov    ax,24
  383.     test    esi,0FFFF0000h  ;/* top word is zero: cnvt to 1.n <3.29> */
  384.     jz    z16l
  385.     sub    ax,16
  386.     shr    esi,16
  387. z16l:
  388.     test    si,0FF00h
  389.     jz    z8l
  390.     sub    ax,8
  391.     shr    esi,8
  392. z8l:
  393.     shl    esi,8       ;/* most ecomonical pos'n */
  394.     bsr    cx,si       ;/* get exact shift */
  395.     neg    cx
  396.     add    cx,13
  397.     add    cx,ax
  398.  
  399.     jz    noshiftl
  400.     jg    lshiftl
  401.  
  402.     neg    cx
  403.     mov    eax,xh      ;/* convert cross product to 1.n   */
  404.     shrd    xl,eax,cl   ;/* need ext. for borderline cases */
  405.     mov    eax,yh
  406.     shrd    yl,eax,cl
  407.     mov    eax,zh
  408.     shrd    zl,eax,cl
  409. noshiftl:
  410.     add    cx,29
  411.     mov    length,cx
  412.     jmp    dshnorm
  413. lshiftl:
  414.     shl    DWORD PTR xl,cl
  415.     shl    DWORD PTR yl,cl
  416.     shl    DWORD PTR zl,cl
  417.  
  418.     mov    ax,29
  419.     sub    ax,cx
  420.     mov    length,ax
  421. dshnorm:
  422.     jmp    finish
  423.  
  424. zero_normal:
  425.     mov    eax,1        ; *xn = *yn = *zn = -1
  426.         mov    xn,eax
  427.     mov    yn,eax
  428.     mov    zn,eax
  429.     mov    WORD PTR length,0    ; return 0
  430.     jmp    rtn_result
  431.  
  432. finish:                     ;/* compute magnitude, convert to unit length */
  433.     mov    eax,xl      ;/* compute squares */
  434.     sar    eax,16
  435.     imul    ax
  436.     mov    bx,dx
  437.     mov    cx,ax
  438.  
  439.     mov    eax,yl
  440.     sar    eax,16
  441.     imul    ax
  442.     add    cx,ax
  443.     adc    bx,dx
  444.  
  445.     mov    eax,zl
  446.     sar    eax,16
  447.     imul    ax
  448.     add    cx,ax
  449.     adc    bx,dx
  450.  
  451.     shr    bx,4             ;/* magnitude << 13 */
  452.     shl    bx,1
  453.     les    si,DWORD PTR _sqrtable
  454.     mov    cx,WORD PTR es:[bx+si]
  455.  
  456.     movzx    ecx,cx
  457.  
  458.     mov    eax,xl           ;/* scale cross product */
  459.     cdq
  460.     shld    edx,eax,13
  461.     shl    eax,13
  462.     idiv    ecx
  463.     mov    xl,eax
  464.  
  465.     mov    eax,yl
  466.     cdq
  467.     shld    edx,eax,13
  468.     shl    eax,13
  469.     idiv    ecx
  470.     mov    yl,eax
  471.  
  472.     mov    eax,zl
  473.     cdq
  474.     shld    edx,eax,13
  475.     shl    eax,13
  476.     idiv    ecx
  477.     mov    zl,eax
  478.  
  479. rtn_result:         ; /* left-hand coordinate system: negate normal */
  480.     les    bx,DWORD PTR xn
  481.     mov    eax,xl
  482.     neg    eax
  483.     mov    DWORD PTR es:[bx],eax
  484.  
  485.     les    bx,DWORD PTR yn
  486.     mov    eax,yl
  487.     neg    eax
  488.     mov    DWORD PTR es:[bx],eax
  489.  
  490.     les    bx,DWORD PTR zn
  491.     mov    eax,zl
  492.     neg    eax
  493.     mov    DWORD PTR es:[bx],eax
  494.  
  495.     mov    ax, length
  496.  
  497.     pop    edx
  498.     pop    ecx
  499.     pop    edi
  500.     pop    esi
  501.  
  502.     mov    esp,ebp
  503.     pop    ebp
  504.     ret
  505.  
  506. _find_normal    endp
  507.  
  508.  
  509.  
  510. ;/******************** APPLY MATRIX TO OBJECTS **************/
  511.  
  512.  
  513. ;void matmove_osphere(OBJECT *obj, MATRIX m)
  514.  
  515. obj    equ    [bp+8]          ; arguments
  516. m    equ    [bp+12]
  517.  
  518.     PUBLIC    _matmove_osphere
  519.  
  520. _matmove_osphere proc    far
  521.  
  522.     .386
  523.     push    ebp
  524.     mov    ebp,esp
  525.  
  526.     push    ds
  527.     push    esi
  528.     push    edi
  529.     push    ecx
  530.     push    edx
  531.  
  532.     lds    si,DWORD PTR m        ; PTR TO MATRIX
  533.  
  534.     les    di,DWORD PTR obj    ; ptr to object
  535.  
  536.     inc    DWORD PTR es:[bx].O_ucount    ; mark as moved
  537.  
  538.     DOTPROD ds:[si],ds:[si+4],ds:[si+8],es:[di].O_osphx,es:[di].O_osphy,es:[di].O_osphz,ds:[si+36]
  539.     mov    es:[di].O_sphx,eax
  540.  
  541.     DOTPROD ds:[si+12],ds:[si+16],ds:[si+20],es:[di].O_osphx,es:[di].O_osphy,es:[di].O_osphz,ds:[si+40]
  542.     mov    es:[di].O_sphy,eax
  543.  
  544.     DOTPROD ds:[si+24],ds:[si+28],ds:[si+32],es:[di].O_osphx,es:[di].O_osphy,es:[di].O_osphz,ds:[si+44]
  545.     mov    es:[di].O_sphz,eax
  546.  
  547.     pop    edx
  548.     pop    ecx
  549.     pop    edi
  550.     pop    esi
  551.     pop    ds
  552.  
  553.     mov    esp,ebp
  554.     pop    ebp
  555.     ret
  556.  
  557. _matmove_osphere    endp
  558.  
  559.  
  560.  
  561.  
  562. ;void matmove_rep(REP *rep, MATRIX m)
  563.  
  564. rep    equ    [bp+8]          ; arguments
  565. m    equ    [bp+12]
  566.  
  567. i    equ    [bp-4]        ; locals
  568. v    equ    [bp-8]
  569. p    equ    [bp-12]
  570. vc    equ    [bp-14]
  571. pc    equ    [bp-16]
  572.  
  573. vs    equ     SIZE VERTEX    ; structure sizes
  574. ps    equ    SIZE POLY
  575.  
  576.     PUBLIC    _matmove_rep
  577.  
  578. _matmove_rep     proc    far
  579.  
  580.     .386
  581.     push    ebp
  582.     mov    ebp,esp
  583.     sub    esp,20
  584.  
  585.     push    ds
  586.     push    esi
  587.     push    edi
  588.     push    ecx
  589.     push    edx
  590.  
  591.     lds    si,DWORD PTR m        ; PTR TO MATRIX
  592.  
  593.     les    di,DWORD PTR rep    ; ptr to rep
  594.  
  595.     mov    eax, es:[di].R_verts    ; get data
  596.     mov    v, eax
  597.     mov    eax, es:[di].R_polys
  598.     mov    p, eax
  599.     mov    ax, es:[di].R_nverts
  600.     mov    vc, ax
  601.     mov    ax, es:[di].R_npolys
  602.     mov    pc, ax
  603.  
  604.     les    di,DWORD PTR v   ;/* rotate/translate all vertices */
  605.  
  606. vconv:
  607.     DOTPROD ds:[si],ds:[si+4],ds:[si+8],es:[di].V_ox,es:[di].V_oy,es:[di].V_oz,ds:[si+36]
  608.     mov    es:[di].V_x,eax
  609.  
  610.     DOTPROD ds:[si+12],ds:[si+16],ds:[si+20],es:[di].V_ox,es:[di].V_oy,es:[di].V_oz,ds:[si+40]
  611.     mov    es:[di].V_y,eax
  612.  
  613.     DOTPROD ds:[si+24],ds:[si+28],ds:[si+32],es:[di].V_ox,es:[di].V_oy,es:[di].V_oz,ds:[si+44]
  614.     mov    es:[di].V_z,eax
  615.  
  616.     add    di,vs
  617.     dec     WORD PTR vc
  618.     jnz     vconv
  619.  
  620.     les    di,DWORD PTR p      ; now for polys: rotate all normals */
  621.  
  622. pconv:
  623.     DOTPROD    ds:[si],ds:[si+4],ds:[si+8],es:[di].P_onormx,es:[di].P_onormy,es:[di].P_onormz,0
  624.     mov    es:[di].P_normx,eax
  625.  
  626.     DOTPROD    ds:[si+12],ds:[si+16],ds:[si+20],es:[di].P_onormx,es:[di].P_onormy,es:[di].P_onormz,0
  627.     mov    es:[di].P_normy,eax
  628.  
  629.     DOTPROD    ds:[si+24],ds:[si+28],ds:[si+32],es:[di].P_onormx,es:[di].P_onormy,es:[di].P_onormz,0
  630.     mov    es:[di].P_normz,eax
  631.  
  632.     add    di,ps
  633.     dec     WORD PTR pc
  634.     jnz     pconv
  635.  
  636.     pop    edx
  637.     pop    ecx
  638.     pop    edi
  639.     pop    esi
  640.     pop    ds
  641.  
  642.     mov    esp,ebp
  643.     pop    ebp
  644.     ret
  645.  
  646. _matmove_rep    endp
  647.  
  648.  
  649.     end
  650.  
  651.  
  652.