Subversion Repositories Kolibri OS

Rev

Rev 5153 | Rev 5256 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; Some simple mathematical functions. Don't look for some logic in
  2. ; the function names :-)
  3.  
  4. ; ******* Gestion des matrices 4x4 ******
  5.  
  6. align 4
  7. proc gl_M4_Id uses eax ecx edi, a:dword
  8.         mov edi,[a]
  9.         add edi,4
  10.         mov ecx,14
  11.         mov eax,0.0
  12.         rep stosd
  13.         mov eax,1.0
  14.         stosd
  15.         mov edi,[a]
  16.         stosd
  17.         add edi,16
  18.         stosd
  19.         add edi,16
  20.         stosd
  21.         ret
  22. endp
  23.  
  24. align 4
  25. proc gl_M4_IsId uses ebx ecx, a:dword
  26.         mov eax,[a]
  27.         xor ebx,ebx
  28.         xor ecx,ecx
  29.         .cycle_01:
  30.                 fld dword[eax]
  31.                 cmp ecx,ebx
  32.                 je .once
  33.                         ftst ;ñðàâíåíèå ñ 0.0
  34.                         fstsw ax
  35.                         sahf
  36.                         je @f
  37.                         jmp .not_1 ;åñëè äèàãîíàëüíûå ÷èñëà íå ðàâíû 0.0 ìàòðèöà íå åäèíè÷íàÿ
  38.                 .once:
  39.                         fld1
  40.                         fcomp st1 ;ñðàâíåíèå ñ 1.0
  41.                         fstsw ax
  42.                         test ah,0x40
  43.                         je .not_1 ;åñëè íå ðàâíî 1.0 ìàòðèöà íå åäèíè÷íàÿ
  44.                 @@:
  45.                 ffree st0
  46.                 fincstp
  47.                 add eax,4
  48.                 inc ebx
  49.                 btr ebx,2
  50.                 jnc .cycle_01
  51.         inc ecx
  52.         bt ecx,2 ;ïðîâåðÿåì ðàâåíñòâî ecx==4
  53.         jnc .cycle_01
  54.  
  55.         mov eax,1
  56.         jmp @f
  57.         .not_1:
  58.                 ffree st0
  59.                 fincstp
  60.                 xor eax,eax
  61.         @@:
  62.         ret
  63. endp
  64.  
  65. align 4
  66. proc gl_M4_Mul, c:dword,a:dword,b:dword
  67. pushad
  68.         mov edx,[c]
  69.         xor eax,eax
  70.         .cycle_0: ;i
  71.                 xor ebx,ebx
  72.                 .cycle_1: ;j
  73.                         finit
  74.                         fldz ;sum=0
  75.                         xor ecx,ecx
  76.                         M4_reg edi,[a],eax,0
  77.                         .cycle_2: ;k
  78.                                 fld dword[edi]
  79.                                 add edi,4
  80.                                 M4_reg esi,[b],ecx,ebx
  81.                                 fmul dword[esi]
  82.                                 fadd st0,st1 ;sum += a[i][k] * b[k][j]
  83.                                 inc ecx
  84.                                 cmp ecx,4
  85.                                 jl .cycle_2
  86.                         fstp dword[edx] ;c[i][j] = sum
  87.                         add edx,4
  88.                         inc ebx
  89.                         cmp ebx,4
  90.                         jl .cycle_1
  91.                 inc eax
  92.                 cmp eax,4
  93.                 jl .cycle_0
  94.         finit
  95. if DEBUG ;gl_M4_Mul
  96.         stdcall dbg_print,f_m4m,txt_nl
  97.         stdcall gl_print_matrix,[c],4
  98.         stdcall dbg_print,txt_sp,txt_nl
  99. end if
  100. popad
  101.         ret
  102. endp
  103.  
  104. ; c=c*a
  105. align 4
  106. proc gl_M4_MulLeft, c:dword,b:dword
  107. locals
  108.         i dd ?
  109.         a M4
  110. endl
  111. pushad
  112.         mov ecx,16
  113.         mov esi,[c]
  114.         mov edi,ebp
  115.         sub edi,sizeof.M4
  116.         rep movsd ;êîïèðîâàíèå ìàòðèö [a]=[c]
  117.  
  118.         mov edx,[c]
  119.         mov dword[i],0
  120.         .cycle_0: ;i
  121.                 xor ebx,ebx
  122.                 .cycle_1: ;j
  123.                         finit
  124.                         fldz ;sum=0
  125.                         xor ecx,ecx
  126.                         mov eax,ebp
  127.                         sub eax,sizeof.M4
  128.                         M4_reg edi,eax,dword[i],0
  129.                         .cycle_2: ;k
  130.                                 fld dword[edi]
  131.                                 add edi,4
  132.                                 M4_reg esi,[b],ecx,ebx
  133.                                 fmul dword[esi]
  134.                                 fadd st0,st1 ;sum += a[i][k] * b[k][j]
  135.                                 inc ecx
  136.                                 add eax,4
  137.                                 cmp ecx,4
  138.                                 jl .cycle_2
  139.                         fstp dword[edx] ;c[i][j] = sum
  140.                         add edx,4
  141.                         inc ebx
  142.                         cmp ebx,4
  143.                         jl .cycle_1
  144.                 inc dword[i]
  145.                 cmp dword[i],4
  146.                 jl .cycle_0
  147.         finit
  148. if DEBUG ;gl_M4_MulLeft
  149.         stdcall dbg_print,f_m4ml,txt_nl
  150.         stdcall gl_print_matrix,[c],4
  151.         stdcall dbg_print,txt_sp,txt_nl
  152. end if
  153. popad
  154.         ret
  155. endp
  156.  
  157. align 4
  158. proc gl_M4_Move uses ecx edi esi, a:dword,b:dword
  159.         mov edi,[a]
  160.         mov esi,[b]
  161.         mov ecx,sizeof.M4/4
  162.         rep movsd
  163.         ret
  164. endp
  165.  
  166. align 4
  167. proc gl_MoveV3 uses edi esi, a:dword,b:dword
  168.         mov edi,[a]
  169.         mov esi,[b]
  170.         movsd
  171.         movsd
  172.         movsd
  173.         ret
  174. endp
  175.  
  176. ;void gl_MulM4V3(V3 *a,M4 *b,V3 *c)
  177. ;{
  178. ;        a->X=b->m[0][0]*c->X+b->m[0][1]*c->Y+b->m[0][2]*c->Z+b->m[0][3];
  179. ;        a->Y=b->m[1][0]*c->X+b->m[1][1]*c->Y+b->m[1][2]*c->Z+b->m[1][3];
  180. ;        a->Z=b->m[2][0]*c->X+b->m[2][1]*c->Y+b->m[2][2]*c->Z+b->m[2][3];
  181. ;}
  182.  
  183. ;void gl_MulM3V3(V3 *a,M4 *b,V3 *c)
  184. ;{
  185. ;        a->X=b->m[0][0]*c->X+b->m[0][1]*c->Y+b->m[0][2]*c->Z;
  186. ;        a->Y=b->m[1][0]*c->X+b->m[1][1]*c->Y+b->m[1][2]*c->Z;
  187. ;        a->Z=b->m[2][0]*c->X+b->m[2][1]*c->Y+b->m[2][2]*c->Z;
  188. ;}
  189.  
  190. ;void gl_M4_MulV4(V4 *a,M4 *b,V4 *c)
  191. ;{
  192. ;        a->X=b->m[0][0]*c->X+b->m[0][1]*c->Y+b->m[0][2]*c->Z+b->m[0][3]*c->W;
  193. ;        a->Y=b->m[1][0]*c->X+b->m[1][1]*c->Y+b->m[1][2]*c->Z+b->m[1][3]*c->W;
  194. ;        a->Z=b->m[2][0]*c->X+b->m[2][1]*c->Y+b->m[2][2]*c->Z+b->m[2][3]*c->W;
  195. ;        a->W=b->m[3][0]*c->X+b->m[3][1]*c->Y+b->m[3][2]*c->Z+b->m[3][3]*c->W;
  196. ;}
  197.  
  198. ; transposition of a 4x4 matrix
  199. align 4
  200. proc gl_M4_Transpose uses eax ecx edx, a:dword, b:dword
  201.         mov eax,[a]
  202.         mov ecx,[b]
  203.  
  204.         mov edx,[ecx]
  205.         mov [eax],edx
  206.         mov edx,[ecx+0x10]
  207.         mov [eax+0x4],edx
  208.         mov edx,[ecx+0x20]
  209.         mov [eax+0x8],edx
  210.         mov edx,[ecx+0x30]
  211.         mov [eax+0x0c],edx
  212.  
  213.         mov edx,[ecx+0x4]
  214.         mov [eax+0x10],edx
  215.         mov edx,[ecx+0x14]
  216.         mov [eax+0x14],edx
  217.         mov edx,[ecx+0x24]
  218.         mov [eax+0x18],edx
  219.         mov edx,[ecx+0x34]
  220.         mov [eax+0x1c],edx
  221.  
  222.         mov edx,[ecx+0x8]
  223.         mov [eax+0x20],edx
  224.         mov edx,[ecx+0x18]
  225.         mov [eax+0x24],edx
  226.         mov edx,[ecx+0x28]
  227.         mov [eax+0x28],edx
  228.         mov edx,[ecx+0x38]
  229.         mov [eax+0x2c],edx
  230.  
  231.         mov edx,[ecx+0x0c]
  232.         mov [eax+0x30],edx
  233.         mov edx,[ecx+0x1c]
  234.         mov [eax+0x34],edx
  235.         mov edx,[ecx+0x2c]
  236.         mov [eax+0x38],edx
  237.         mov edx,[ecx+0x3c]
  238.         mov [eax+0x3c],edx
  239.         ret
  240. endp
  241.  
  242. ; inversion of an orthogonal matrix of type Y=M.X+P
  243. ;void gl_M4_InvOrtho(M4 *a,M4 b)
  244. ;{
  245. ;       int i,j;
  246. ;       float s;
  247. ;       for(i=0;i<3;i++)
  248. ;       for(j=0;j<3;j++) a->m[i][j]=b.m[j][i];
  249. ;       a->m[3][0]=0.0; a->m[3][1]=0.0; a->m[3][2]=0.0; a->m[3][3]=1.0;
  250. ;       for(i=0;i<3;i++) {
  251. ;               s=0;
  252. ;               for(j=0;j<3;j++) s-=b.m[j][i]*b.m[j][3];
  253. ;               a->m[i][3]=s;
  254. ;       }
  255. ;}
  256.  
  257. ; Inversion of a general nxn matrix.
  258. ; Note : m is destroyed
  259.  
  260. align 4
  261. proc Matrix_Inv uses ecx, r:dword, m:dword, n:dword ;(float *r,float *m,int n)
  262. ;        int i,j,k,l;
  263. ;        float max,tmp,t;
  264.  
  265. ;        /* identitée dans r */
  266. ;        for(i=0;i<n*n;i++) r[i]=0;
  267. ;        for(i=0;i<n;i++) r[i*n+i]=1;
  268.          
  269. ;        for(j=0;j<n;j++) {
  270.                        
  271. ;                       /* recherche du nombre de plus grand module sur la colonne j */
  272. ;                       max=m[j*n+j];
  273. ;                       k=j;
  274. ;                       for(i=j+1;i<n;i++)
  275. ;                               if (fabs(m[i*n+j])>fabs(max)) {
  276. ;                                        k=i;
  277. ;                                        max=m[i*n+j];
  278. ;                               }
  279.  
  280. ;      /* non intersible matrix */
  281. ;      if (max==0) return 1;
  282.  
  283. ;                       /* permutation des lignes j et k */
  284. ;                       if (k!=j) {
  285. ;                                for(i=0;i<n;i++) {
  286. ;                                               tmp=m[j*n+i];
  287. ;                                               m[j*n+i]=m[k*n+i];
  288. ;                                               m[k*n+i]=tmp;
  289. ;                                              
  290. ;                                               tmp=r[j*n+i];
  291. ;                                               r[j*n+i]=r[k*n+i];
  292. ;                                               r[k*n+i]=tmp;
  293. ;                                }
  294. ;                       }
  295.  
  296. ;                       /* multiplication de la ligne j par 1/max */
  297. ;                       max=1/max;
  298. ;                       for(i=0;i<n;i++) {
  299. ;                                m[j*n+i]*=max;
  300. ;                                r[j*n+i]*=max;
  301. ;                       }
  302.  
  303. ;                       for(l=0;l<n;l++) if (l!=j) {
  304. ;                                t=m[l*n+j];
  305. ;                                for(i=0;i<n;i++) {
  306. ;                                               m[l*n+i]-=m[j*n+i]*t;
  307. ;                                               r[l*n+i]-=r[j*n+i]*t;
  308. ;                                }
  309. ;                       }
  310. ;        }
  311.  
  312. ;        return 0;
  313.         ret
  314. endp
  315.  
  316. ; inversion of a 4x4 matrix
  317.  
  318. align 4
  319. proc gl_M4_Inv uses eax ecx edi esi, a:dword, b:dword
  320. locals
  321.         tmp M4
  322. endl
  323.         mov esi,[b]
  324.         mov edi,ebp
  325.         sub edi,sizeof.M4 ;edi = &tmp
  326.         mov ecx,16
  327.         rep movsd
  328.         sub edi,sizeof.M4 ;edi = &tmp
  329.         stdcall Matrix_Inv,[a],edi,4 ;ïîðòèò eax ïîòîìó â uses åñòü eax
  330.         ret
  331. endp
  332.  
  333. align 4
  334. proc gl_M4_Rotate uses eax ecx, a:dword,t:dword,u:dword
  335. locals
  336.         s dd ? ;float
  337.         c dd ? ;float
  338.         v dd ? ;int
  339.         w dd ? ;int
  340. endl
  341.         mov eax,[u]
  342.         inc eax
  343.         mov dword [v],eax
  344.         cmp dword [v],2
  345.         jle @f
  346.                 mov dword [v],0
  347.         @@:
  348.         mov eax,[v]
  349.         inc eax
  350.         mov dword [w],eax
  351.         cmp dword [w],2
  352.         jle @f
  353.                 mov dword [w],0
  354.         @@:
  355.         fld dword [t]
  356.         fsin
  357.         fstp dword [s]
  358.         fld dword [t]
  359.         fcos
  360.         fstp dword [c]
  361.  
  362.         stdcall gl_M4_Id,[a]
  363.  
  364.         M4_reg ecx,[a],[v],[v]
  365.         mov eax,[c]
  366.         mov [ecx],eax
  367.  
  368.         M4_reg ecx,[a],[v],[w]
  369.         fld dword [s]
  370.         fchs
  371.         fstp dword [ecx]
  372.  
  373.         M4_reg ecx,[a],[w],[v]
  374.         mov eax,[s]
  375.         mov [ecx],eax
  376.  
  377.         M4_reg ecx,[a],[w],[w]
  378.         mov eax,[c]
  379.         mov [ecx],eax
  380.  
  381.         ret
  382. endp
  383.  
  384. ; inverse of a 3x3 matrix
  385. ;void gl_M3_Inv(M3 *a,M3 *m)
  386. ;{
  387. ;        float det;
  388.  
  389. ;        det = m->m[0][0]*m->m[1][1]*m->m[2][2]-m->m[0][0]*m->m[1][2]*m->m[2][1]-
  390. ;                m->m[1][0]*m->m[0][1]*m->m[2][2]+m->m[1][0]*m->m[0][2]*m->m[2][1]+
  391. ;                m->m[2][0]*m->m[0][1]*m->m[1][2]-m->m[2][0]*m->m[0][2]*m->m[1][1];
  392.  
  393. ;        a->m[0][0] = (m->m[1][1]*m->m[2][2]-m->m[1][2]*m->m[2][1])/det;
  394. ;        a->m[0][1] = -(m->m[0][1]*m->m[2][2]-m->m[0][2]*m->m[2][1])/det;
  395. ;        a->m[0][2] = -(-m->m[0][1]*m->m[1][2]+m->m[0][2]*m->m[1][1])/det;
  396.  
  397. ;        a->m[1][0] = -(m->m[1][0]*m->m[2][2]-m->m[1][2]*m->m[2][0])/det;
  398. ;        a->m[1][1] = (m->m[0][0]*m->m[2][2]-m->m[0][2]*m->m[2][0])/det;
  399. ;        a->m[1][2] = -(m->m[0][0]*m->m[1][2]-m->m[0][2]*m->m[1][0])/det;
  400.  
  401. ;        a->m[2][0] = (m->m[1][0]*m->m[2][1]-m->m[1][1]*m->m[2][0])/det;
  402. ;        a->m[2][1] = -(m->m[0][0]*m->m[2][1]-m->m[0][1]*m->m[2][0])/det;
  403. ;        a->m[2][2] = (m->m[0][0]*m->m[1][1]-m->m[0][1]*m->m[1][0])/det;
  404. ;}
  405.  
  406. ; vector arithmetic
  407.  
  408. align 4
  409. proc gl_V3_Norm uses ebx, a:dword
  410.         mov ebx,[a]
  411.         fld dword[ebx]
  412.         fmul dword[ebx]
  413.         fld dword[ebx+4]
  414.         fmul dword[ebx+4]
  415.         faddp
  416.         fld dword[ebx+8]
  417.         fmul dword[ebx+8]
  418.         faddp
  419.         fsqrt ;st0 = sqrt(a.X^2 +a.Y^2 +a.Z^2)
  420.         fldz
  421.         fcomp
  422.         fstsw ax
  423.         sahf
  424.         je .r1 ;if (sqrt(...)==0) return 1
  425.                 fld dword[ebx] ;offs_X = 0
  426.                 fdiv st0,st1
  427.                 fstp dword[ebx] ;a.X/=sqrt(...)
  428.                 fld dword[ebx+4]
  429.                 fdiv st0,st1
  430.                 fstp dword[ebx+4] ;a.Y/=sqrt(...)
  431.                 fld dword[ebx+8]
  432.                 fdiv st0,st1
  433.                 fstp dword[ebx+8] ;a.Z/=sqrt(...)
  434.                 xor eax,eax
  435.                 jmp @f
  436.         .r1:
  437.                 xor eax,eax
  438.                 inc eax
  439.         @@:
  440.         ffree st0
  441.         fincstp
  442.         ret
  443. endp
  444.  
  445. macro gl_V3_New p_mem, x, y, z
  446. {
  447.         mov dword[p_mem],x
  448.         mov dword[p_mem+4],y
  449.         mov dword[p_mem+8],z
  450. }
  451.  
  452. macro gl_V4_New p_mem, x, y, z, w
  453. {
  454.         mov dword[p_mem],x
  455.         mov dword[p_mem+4],y
  456.         mov dword[p_mem+8],z
  457.         mov dword[p_mem+12],w
  458. }
  459.