Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
5153 IgorA 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
		@@:
5218 IgorA 45
		ffree st0
46
		fincstp
5153 IgorA 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:
5218 IgorA 58
		ffree st0
59
		fincstp
5153 IgorA 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
 
5218 IgorA 242
; inversion of an orthogonal matrix of type Y=M.X+P
5153 IgorA 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
 
5218 IgorA 257
; Inversion of a general nxn matrix.
258
; Note : m is destroyed
5153 IgorA 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
267
;        for(i=0;i
268
 
269
;        for(j=0;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
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
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
299
;                                m[j*n+i]*=max;
300
;                                r[j*n+i]*=max;
301
;                       }
302
 
303
;                       for(l=0;l
304
;                                t=m[l*n+j];
305
;                                for(i=0;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
 
5218 IgorA 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
5153 IgorA 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
}