source: trunk/Packages/bgrabitmap/bgramatrix3d.pas

Last change on this file was 2, checked in by chronos, 5 years ago
File size: 17.5 KB
Line 
1unit BGRAMatrix3D;
2
3{$mode objfpc}{$H+}
4
5{$i bgrasse.inc}
6
7{$ifdef CPUI386}
8 {$asmmode intel}
9{$ENDIF}
10{$ifdef cpux86_64}
11 {$asmmode intel}
12{$ENDIF}
13
14interface
15
16uses
17 BGRABitmapTypes, BGRASSE,
18 BGRATransform;
19
20type
21 TMatrix3D = packed array[1..3,1..4] of single;
22 TMatrix4D = packed array[1..4,1..4] of single;
23 TProjection3D = packed record
24 Zoom, Center: TPointF;
25 end;
26 TComputeProjectionFunc = function(AViewCoord: TPoint3D_128): TPointF of object;
27
28operator*(const A: TMatrix3D; const M: TPoint3D): TPoint3D;
29operator*(constref A: TMatrix3D; var M: TPoint3D_128): TPoint3D_128;
30function MultiplyVect3DWithoutTranslation(constref A: TMatrix3D; constref M: TPoint3D_128): TPoint3D_128;
31operator*(A,B: TMatrix3D): TMatrix3D;
32
33function Matrix3D(m11,m12,m13,m14, m21,m22,m23,m24, m31,m32,m33,m34: single): TMatrix3D; overload;
34function Matrix3D(vx,vy,vz,ofs: TPoint3D): TMatrix3D; overload;
35function Matrix3D(vx,vy,vz,ofs: TPoint3D_128): TMatrix3D; overload;
36function MatrixIdentity3D: TMatrix3D;
37function MatrixInverse3D(A: TMatrix3D): TMatrix3D;
38function MatrixTranslation3D(ofs: TPoint3D): TMatrix3D;
39function MatrixScale3D(size: TPoint3D): TMatrix3D;
40function MatrixRotateX(angle: single): TMatrix3D;
41function MatrixRotateY(angle: single): TMatrix3D;
42function MatrixRotateZ(angle: single): TMatrix3D;
43
44operator *(const A, B: TMatrix4D): TMatrix4D;
45function MatrixIdentity4D: TMatrix4D;
46function AffineMatrixToMatrix4D(AValue: TAffineMatrix): TMatrix4D;
47
48{$IFDEF BGRASSE_AVAILABLE}
49procedure Matrix3D_SSE_Load(const A: TMatrix3D);
50procedure MatrixMultiplyVect3D_SSE_Aligned(var M: TPoint3D_128; out N: TPoint3D_128);
51procedure MatrixMultiplyVect3D_SSE3_Aligned(var M: TPoint3D_128; out N: TPoint3D_128);
52procedure MatrixMultiplyVect3DWithoutTranslation_SSE_Aligned(var M: TPoint3D_128; out N: TPoint3D_128);
53procedure MatrixMultiplyVect3DWithoutTranslation_SSE3_Aligned(var M: TPoint3D_128; out N: TPoint3D_128);
54{$ENDIF}
55
56implementation
57
58procedure multiplyVect3(const A : TMatrix3D; const vx,vy,vz,vt: single; out outx,outy,outz: single);
59begin
60 outx := vx * A[1,1] + vy * A[1,2] + vz * A[1,3] + vt * A[1,4];
61 outy := vx * A[2,1] + vy * A[2,2] + vz * A[2,3] + vt * A[2,4];
62 outz := vx * A[3,1] + vy * A[3,2] + vz * A[3,3] + vt * A[3,4];
63end;
64
65procedure multiplyVect4(const A : TMatrix4D; const vx,vy,vz,vt: single; out outx,outy,outz,outt: single);
66begin
67 outx := vx * A[1,1] + vy * A[1,2] + vz * A[1,3] + vt * A[1,4];
68 outy := vx * A[2,1] + vy * A[2,2] + vz * A[2,3] + vt * A[2,4];
69 outz := vx * A[3,1] + vy * A[3,2] + vz * A[3,3] + vt * A[3,4];
70 outt := vx * A[4,1] + vy * A[4,2] + vz * A[4,3] + vt * A[4,4];
71end;
72
73operator*(const A: TMatrix3D; const M: TPoint3D): TPoint3D;
74begin
75 result.x := M.x * A[1,1] + M.y * A[1,2] + M.z * A[1,3] + A[1,4];
76 result.y := M.x * A[2,1] + M.y * A[2,2] + M.z * A[2,3] + A[2,4];
77 result.z := M.x * A[3,1] + M.y * A[3,2] + M.z * A[3,3] + A[3,4];
78end;
79
80operator*(const A, B: TMatrix4D): TMatrix4D;
81begin
82 multiplyVect4(A, B[1,1],B[2,1],B[3,1],B[4,1], result[1,1],result[2,1],result[3,1],result[4,1]);
83 multiplyVect4(A, B[1,2],B[2,2],B[3,2],B[4,2], result[1,2],result[2,2],result[3,2],result[4,2]);
84 multiplyVect4(A, B[1,3],B[2,3],B[3,3],B[4,3], result[1,3],result[2,3],result[3,3],result[4,3]);
85 multiplyVect4(A, B[1,4],B[2,4],B[3,4],B[4,4], result[1,4],result[2,4],result[3,4],result[4,4]);
86end;
87
88function MatrixIdentity4D: TMatrix4D;
89begin
90 result[1,1] := 1; result[2,1] := 0; result[3,1] := 0; result[4,1] := 0;
91 result[1,2] := 0; result[2,2] := 1; result[3,2] := 0; result[4,2] := 0;
92 result[1,3] := 0; result[2,3] := 0; result[3,3] := 1; result[4,3] := 0;
93 result[1,4] := 0; result[2,4] := 0; result[3,4] := 0; result[4,4] := 1;
94end;
95
96function AffineMatrixToMatrix4D(AValue: TAffineMatrix): TMatrix4D;
97begin
98 result[1,1] := AValue[1,1]; result[2,1] := AValue[1,2]; result[3,1] := 0; result[4,1] := AValue[1,3];
99 result[1,2] := AValue[2,1]; result[2,2] := AValue[2,2]; result[3,2] := 0; result[4,2] := AValue[2,3];
100 result[1,3] := 0; result[2,3] := 0; result[3,3] := 1; result[4,3] := 0;
101 result[1,4] := 0; result[2,4] := 0; result[3,4] := 0; result[4,4] := 1;
102end;
103
104{$IFDEF BGRASSE_AVAILABLE}
105var SingleConst1 : single = 1;
106
107 procedure Matrix3D_SSE_Load(const A: TMatrix3D);
108 begin
109 {$IFDEF cpux86_64}
110 asm
111 mov rax, A
112 movups xmm5, [rax]
113 movups xmm6, [rax+16]
114 movups xmm7, [rax+32]
115 end;
116 {$ELSE}
117 asm
118 mov eax, A
119 movups xmm5, [eax]
120 movups xmm6, [eax+16]
121 movups xmm7, [eax+32]
122 end;
123 {$ENDIF}
124 end;
125
126procedure MatrixMultiplyVect3D_SSE_Aligned(var M: TPoint3D_128; out N: TPoint3D_128);
127var oldMt: single;
128begin
129 oldMt := M.t;
130 M.t := SingleConst1;
131 {$IFDEF cpux86_64}
132 asm
133 mov rax, M
134 movaps xmm0, [rax]
135
136 mov rax, N
137
138 movaps xmm2,xmm0
139 mulps xmm2,xmm5
140 //mix1
141 movaps xmm3, xmm2
142 shufps xmm3, xmm3, $4e
143 addps xmm2, xmm3
144 //mix2
145 movaps xmm3, xmm2
146 shufps xmm3, xmm3, $11
147 addps xmm2, xmm3
148
149 movss [rax], xmm2
150
151 movaps xmm2,xmm0
152 mulps xmm2,xmm6
153 //mix1
154 movaps xmm3, xmm2
155 shufps xmm3, xmm3, $4e
156 addps xmm2, xmm3
157 //mix2
158 movaps xmm3, xmm2
159 shufps xmm3, xmm3, $11
160 addps xmm2, xmm3
161
162 movss [rax+4], xmm2
163
164 mulps xmm0,xmm7
165 //mix1
166 movaps xmm3, xmm0
167 shufps xmm3, xmm3, $4e
168 addps xmm0, xmm3
169 //mix2
170 movaps xmm3, xmm0
171 shufps xmm3, xmm3, $11
172 addps xmm0, xmm3
173
174 movss [rax+8], xmm0
175 end;
176 {$ELSE}
177 asm
178 mov eax, M
179 movaps xmm0, [eax]
180
181 mov eax, N
182
183 movaps xmm2,xmm0
184 mulps xmm2,xmm5
185 //mix1
186 movaps xmm3, xmm2
187 shufps xmm3, xmm3, $4e
188 addps xmm2, xmm3
189 //mix2
190 movaps xmm3, xmm2
191 shufps xmm3, xmm3, $11
192 addps xmm2, xmm3
193
194 movss [eax], xmm2
195
196 movaps xmm2,xmm0
197 mulps xmm2,xmm6
198 //mix1
199 movaps xmm3, xmm2
200 shufps xmm3, xmm3, $4e
201 addps xmm2, xmm3
202 //mix2
203 movaps xmm3, xmm2
204 shufps xmm3, xmm3, $11
205 addps xmm2, xmm3
206
207 movss [eax+4], xmm2
208
209 mulps xmm0,xmm7
210 //mix1
211 movaps xmm3, xmm0
212 shufps xmm3, xmm3, $4e
213 addps xmm0, xmm3
214 //mix2
215 movaps xmm3, xmm0
216 shufps xmm3, xmm3, $11
217 addps xmm0, xmm3
218
219 movss [eax+8], xmm0
220 end;
221 {$ENDIF}
222 M.t := oldMt;
223 N.t := 0;
224end;
225
226procedure MatrixMultiplyVect3D_SSE3_Aligned(var M: TPoint3D_128; out N: TPoint3D_128);
227var oldMt: single;
228begin
229 oldMt := M.t;
230 M.t := SingleConst1;
231 {$IFDEF cpux86_64}
232 asm
233 mov rax, M
234 movaps xmm0, [rax]
235
236 mov rax, N
237
238 movaps xmm2,xmm0
239 mulps xmm2,xmm5
240 haddps xmm2,xmm2
241 haddps xmm2,xmm2
242 movss [rax], xmm2
243
244 movaps xmm2,xmm0
245 mulps xmm2,xmm6
246 haddps xmm2,xmm2
247 haddps xmm2,xmm2
248 movss [rax+4], xmm2
249
250 mulps xmm0,xmm7
251 haddps xmm0,xmm0
252 haddps xmm0,xmm0
253 movss [rax+8], xmm0
254 end;
255 {$ELSE}
256 asm
257 mov eax, M
258 movaps xmm0, [eax]
259
260 mov eax, N
261
262 movaps xmm2,xmm0
263 mulps xmm2,xmm5
264 haddps xmm2,xmm2
265 haddps xmm2,xmm2
266 movss [eax], xmm2
267
268 movaps xmm2,xmm0
269 mulps xmm2,xmm6
270 haddps xmm2,xmm2
271 haddps xmm2,xmm2
272 movss [eax+4], xmm2
273
274 mulps xmm0,xmm7
275 haddps xmm0,xmm0
276 haddps xmm0,xmm0
277 movss [eax+8], xmm0
278 end;
279 {$ENDIF}
280 M.t := oldMt;
281end;
282
283procedure MatrixMultiplyVect3DWithoutTranslation_SSE_Aligned(
284 var M: TPoint3D_128; out N: TPoint3D_128);
285begin
286 {$IFDEF cpux86_64}
287 asm
288 mov rax, M
289 movaps xmm0, [rax]
290
291 mov rax, N
292
293 movaps xmm2,xmm0
294 mulps xmm2,xmm5
295 //mix1
296 movaps xmm3, xmm2
297 shufps xmm3, xmm3, $4e
298 addps xmm2, xmm3
299 //mix2
300 movaps xmm3, xmm2
301 shufps xmm3, xmm3, $11
302 addps xmm2, xmm3
303
304 movss [rax], xmm2
305
306 movaps xmm2,xmm0
307 mulps xmm2,xmm6
308 //mix1
309 movaps xmm3, xmm2
310 shufps xmm3, xmm3, $4e
311 addps xmm2, xmm3
312 //mix2
313 movaps xmm3, xmm2
314 shufps xmm3, xmm3, $11
315 addps xmm2, xmm3
316
317 movss [rax+4], xmm2
318
319 mulps xmm0,xmm7
320 //mix1
321 movaps xmm3, xmm0
322 shufps xmm3, xmm3, $4e
323 addps xmm0, xmm3
324 //mix2
325 movaps xmm3, xmm0
326 shufps xmm3, xmm3, $11
327 addps xmm0, xmm3
328
329 movss [rax+8], xmm0
330 end;
331 {$ELSE}
332 asm
333 mov eax, M
334 movaps xmm0, [eax]
335
336 mov eax, N
337
338 movaps xmm2,xmm0
339 mulps xmm2,xmm5
340 //mix1
341 movaps xmm3, xmm2
342 shufps xmm3, xmm3, $4e
343 addps xmm2, xmm3
344 //mix2
345 movaps xmm3, xmm2
346 shufps xmm3, xmm3, $11
347 addps xmm2, xmm3
348
349 movss [eax], xmm2
350
351 movaps xmm2,xmm0
352 mulps xmm2,xmm6
353 //mix1
354 movaps xmm3, xmm2
355 shufps xmm3, xmm3, $4e
356 addps xmm2, xmm3
357 //mix2
358 movaps xmm3, xmm2
359 shufps xmm3, xmm3, $11
360 addps xmm2, xmm3
361
362 movss [eax+4], xmm2
363
364 mulps xmm0,xmm7
365 //mix1
366 movaps xmm3, xmm0
367 shufps xmm3, xmm3, $4e
368 addps xmm0, xmm3
369 //mix2
370 movaps xmm3, xmm0
371 shufps xmm3, xmm3, $11
372 addps xmm0, xmm3
373
374 movss [eax+8], xmm0
375 end;
376 {$ENDIF}
377end;
378
379procedure MatrixMultiplyVect3DWithoutTranslation_SSE3_Aligned(
380 var M: TPoint3D_128; out N: TPoint3D_128);
381begin
382 {$IFDEF cpux86_64}
383 asm
384 mov rax, M
385 movaps xmm0, [rax]
386
387 mov rax, N
388
389 movaps xmm2,xmm0
390 mulps xmm2,xmm5
391 haddps xmm2,xmm2
392 haddps xmm2,xmm2
393 movss [rax], xmm2
394
395 movaps xmm2,xmm0
396 mulps xmm2,xmm6
397 haddps xmm2,xmm2
398 haddps xmm2,xmm2
399 movss [rax+4], xmm2
400
401 mulps xmm0,xmm7
402 haddps xmm0,xmm0
403 haddps xmm0,xmm0
404 movss [rax+8], xmm0
405 end;
406 {$ELSE}
407 asm
408 mov eax, M
409 movaps xmm0, [eax]
410
411 mov eax, N
412
413 movaps xmm2,xmm0
414 mulps xmm2,xmm5
415 haddps xmm2,xmm2
416 haddps xmm2,xmm2
417 movss [eax], xmm2
418
419 movaps xmm2,xmm0
420 mulps xmm2,xmm6
421 haddps xmm2,xmm2
422 haddps xmm2,xmm2
423 movss [eax+4], xmm2
424
425 mulps xmm0,xmm7
426 haddps xmm0,xmm0
427 haddps xmm0,xmm0
428 movss [eax+8], xmm0
429 end;
430 {$ENDIF}
431end;
432
433{$ENDIF}
434
435operator*(constref A: TMatrix3D; var M: TPoint3D_128): TPoint3D_128;
436{$IFDEF BGRASSE_AVAILABLE}var oldMt: single; resultAddr: pointer;{$ENDIF}
437begin
438 {$IFDEF BGRASSE_AVAILABLE}
439 if UseSSE then
440 begin
441 oldMt := M.t;
442 M.t := SingleConst1;
443 resultAddr := @result;
444 {$IFDEF cpux86_64}
445 if UseSSE3 then
446 asm
447 mov rax, A
448 movups xmm5, [rax]
449 movups xmm6, [rax+16]
450 movups xmm7, [rax+32]
451
452 mov rax, M
453 movups xmm0, [rax]
454
455 mov rax, resultAddr
456
457 movaps xmm4,xmm0
458 mulps xmm4,xmm5
459 haddps xmm4,xmm4
460 haddps xmm4,xmm4
461 movss [rax], xmm4
462
463 movaps xmm4,xmm0
464 mulps xmm4,xmm6
465 haddps xmm4,xmm4
466 haddps xmm4,xmm4
467 movss [rax+4], xmm4
468
469 mulps xmm0,xmm7
470 haddps xmm0,xmm0
471 haddps xmm0,xmm0
472 movss [rax+8], xmm0
473 end else
474 asm
475 mov rax, A
476 movups xmm5, [rax]
477 movups xmm6, [rax+16]
478 movups xmm7, [rax+32]
479
480 mov rax, M
481 movups xmm0, [rax]
482
483 mov rax, resultAddr
484
485 movaps xmm4,xmm0
486 mulps xmm4,xmm5
487 //mix1
488 movaps xmm3, xmm4
489 shufps xmm3, xmm3, $4e
490 addps xmm4, xmm3
491 //mix2
492 movaps xmm3, xmm4
493 shufps xmm3, xmm3, $11
494 addps xmm4, xmm3
495
496 movss [rax], xmm4
497
498 movaps xmm4,xmm0
499 mulps xmm4,xmm6
500 //mix1
501 movaps xmm3, xmm4
502 shufps xmm3, xmm3, $4e
503 addps xmm4, xmm3
504 //mix2
505 movaps xmm3, xmm4
506 shufps xmm3, xmm3, $11
507 addps xmm4, xmm3
508
509 movss [rax+4], xmm4
510
511 mulps xmm0,xmm7
512 //mix1
513 movaps xmm3, xmm0
514 shufps xmm3, xmm3, $4e
515 addps xmm0, xmm3
516 //mix2
517 movaps xmm3, xmm0
518 shufps xmm3, xmm3, $11
519 addps xmm0, xmm3
520
521 movss [rax+8], xmm0
522 end;
523 {$ELSE}
524 if UseSSE3 then
525 asm
526 mov eax, A
527 movups xmm5, [eax]
528 movups xmm6, [eax+16]
529 movups xmm7, [eax+32]
530
531 mov eax, M
532 movups xmm0, [eax]
533
534 mov eax, resultAddr
535
536 movaps xmm4,xmm0
537 mulps xmm4,xmm5
538 haddps xmm4,xmm4
539 haddps xmm4,xmm4
540 movss [eax], xmm4
541
542 movaps xmm4,xmm0
543 mulps xmm4,xmm6
544 haddps xmm4,xmm4
545 haddps xmm4,xmm4
546 movss [eax+4], xmm4
547
548 mulps xmm0,xmm7
549 haddps xmm0,xmm0
550 haddps xmm0,xmm0
551 movss [eax+8], xmm0
552 end else
553 asm
554 mov eax, A
555 movups xmm5, [eax]
556 movups xmm6, [eax+16]
557 movups xmm7, [eax+32]
558
559 mov eax, M
560 movups xmm0, [eax]
561
562 mov eax, resultAddr
563
564 movaps xmm4,xmm0
565 mulps xmm4,xmm5
566 //mix1
567 movaps xmm3, xmm4
568 shufps xmm3, xmm3, $4e
569 addps xmm4, xmm3
570 //mix2
571 movaps xmm3, xmm4
572 shufps xmm3, xmm3, $11
573 addps xmm4, xmm3
574
575 movss [eax], xmm4
576
577 movaps xmm4,xmm0
578 mulps xmm4,xmm6
579 //mix1
580 movaps xmm3, xmm4
581 shufps xmm3, xmm3, $4e
582 addps xmm4, xmm3
583 //mix2
584 movaps xmm3, xmm4
585 shufps xmm3, xmm3, $11
586 addps xmm4, xmm3
587
588 movss [eax+4], xmm4
589
590 mulps xmm0,xmm7
591 //mix1
592 movaps xmm3, xmm0
593 shufps xmm3, xmm3, $4e
594 addps xmm0, xmm3
595 //mix2
596 movaps xmm3, xmm0
597 shufps xmm3, xmm3, $11
598 addps xmm0, xmm3
599
600 movss [eax+8], xmm0
601 end;
602 {$ENDIF}
603 M.t := oldMt;
604 result.t := 0;
605 end else
606 {$ENDIF}
607 begin
608 result.x := M.x * A[1,1] + M.y * A[1,2] + M.z * A[1,3] + A[1,4];
609 result.y := M.x * A[2,1] + M.y * A[2,2] + M.z * A[2,3] + A[2,4];
610 result.z := M.x * A[3,1] + M.y * A[3,2] + M.z * A[3,3] + A[3,4];
611 result.t := 0;
612 end;
613end;
614
615function MultiplyVect3DWithoutTranslation(constref A: TMatrix3D; constref M: TPoint3D_128): TPoint3D_128;
616begin
617 {$IFDEF BGRASSE_AVAILABLE}
618 if UseSSE then
619 begin
620 if UseSSE3 then
621 asm
622 mov eax, A
623 movups xmm5, [eax]
624 movups xmm6, [eax+16]
625 movups xmm7, [eax+32]
626
627 mov eax, M
628 movups xmm0, [eax]
629
630 mov eax, result
631
632 movaps xmm4,xmm0
633 mulps xmm4,xmm5
634 haddps xmm4,xmm4
635 haddps xmm4,xmm4
636 movss [eax], xmm4
637
638 movaps xmm4,xmm0
639 mulps xmm4,xmm6
640 haddps xmm4,xmm4
641 haddps xmm4,xmm4
642 movss [eax+4], xmm4
643
644 mulps xmm0,xmm7
645 haddps xmm0,xmm0
646 haddps xmm0,xmm0
647 movss [eax+8], xmm0
648 end else
649 asm
650 mov eax, A
651 movups xmm5, [eax]
652 movups xmm6, [eax+16]
653 movups xmm7, [eax+32]
654
655 mov eax, M
656 movups xmm0, [eax]
657
658 mov eax, result
659
660 movaps xmm4,xmm0
661 mulps xmm4,xmm5
662 //mix1
663 movaps xmm3, xmm4
664 shufps xmm3, xmm3, $4e
665 addps xmm4, xmm3
666 //mix2
667 movaps xmm3, xmm4
668 shufps xmm3, xmm3, $11
669 addps xmm4, xmm3
670
671 movss [eax], xmm4
672
673 movaps xmm4,xmm0
674 mulps xmm4,xmm6
675 //mix1
676 movaps xmm3, xmm4
677 shufps xmm3, xmm3, $4e
678 addps xmm4, xmm3
679 //mix2
680 movaps xmm3, xmm4
681 shufps xmm3, xmm3, $11
682 addps xmm4, xmm3
683
684 movss [eax+4], xmm4
685
686 mulps xmm0,xmm7
687 //mix1
688 movaps xmm3, xmm0
689 shufps xmm3, xmm3, $4e
690 addps xmm0, xmm3
691 //mix2
692 movaps xmm3, xmm0
693 shufps xmm3, xmm3, $11
694 addps xmm0, xmm3
695
696 movss [eax+8], xmm0
697 end;
698 end else
699 {$ENDIF}
700 begin
701 result.x := M.x * A[1,1] + M.y * A[1,2] + M.z * A[1,3];
702 result.y := M.x * A[2,1] + M.y * A[2,2] + M.z * A[2,3];
703 result.z := M.x * A[3,1] + M.y * A[3,2] + M.z * A[3,3];
704 result.t := 0;
705 end;
706end;
707
708operator*(A,B: TMatrix3D): TMatrix3D;
709begin
710 multiplyVect3(A, B[1,1],B[2,1],B[3,1],0, result[1,1],result[2,1],result[3,1]);
711 multiplyVect3(A, B[1,2],B[2,2],B[3,2],0, result[1,2],result[2,2],result[3,2]);
712 multiplyVect3(A, B[1,3],B[2,3],B[3,3],0, result[1,3],result[2,3],result[3,3]);
713 multiplyVect3(A, B[1,4],B[2,4],B[3,4],1, result[1,4],result[2,4],result[3,4]);
714end;
715
716function MatrixIdentity3D: TMatrix3D;
717begin
718 result := Matrix3D( 1,0,0,0,
719 0,1,0,0,
720 0,0,1,0);
721end;
722
723function Matrix3D(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33,
724 m34: single): TMatrix3D;
725begin
726 result[1,1] := m11;
727 result[1,2] := m12;
728 result[1,3] := m13;
729 result[1,4] := m14;
730
731 result[2,1] := m21;
732 result[2,2] := m22;
733 result[2,3] := m23;
734 result[2,4] := m24;
735
736 result[3,1] := m31;
737 result[3,2] := m32;
738 result[3,3] := m33;
739 result[3,4] := m34;
740end;
741
742function MatrixInverse3D(A: TMatrix3D): TMatrix3D;
743var ofs: TPoint3D;
744begin
745 ofs := Point3D(A[1,4],A[2,4],A[3,4]);
746
747 result[1,1] := A[1,1];
748 result[1,2] := A[2,1];
749 result[1,3] := A[3,1];
750 result[1,4] := 0;
751
752 result[2,1] := A[1,2];
753 result[2,2] := A[2,2];
754 result[2,3] := A[3,2];
755 result[2,4] := 0;
756
757 result[3,1] := A[1,3];
758 result[3,2] := A[2,3];
759 result[3,3] := A[3,3];
760 result[3,4] := 0;
761
762 result := result*MatrixTranslation3D(-ofs);
763end;
764
765function Matrix3D(vx, vy, vz, ofs: TPoint3D): TMatrix3D;
766begin
767 result := Matrix3D(vx.x, vy.x, vz.x, ofs.x,
768 vx.y, vy.y, vz.y, ofs.y,
769 vx.z, vy.z, vz.z, ofs.z);
770end;
771
772function Matrix3D(vx, vy, vz, ofs: TPoint3D_128): TMatrix3D;
773begin
774 result := Matrix3D(vx.x, vy.x, vz.x, ofs.x,
775 vx.y, vy.y, vz.y, ofs.y,
776 vx.z, vy.z, vz.z, ofs.z);
777end;
778
779function MatrixTranslation3D(ofs: TPoint3D): TMatrix3D;
780begin
781 result := Matrix3D(1,0,0,ofs.x,
782 0,1,0,ofs.Y,
783 0,0,1,ofs.z);
784end;
785
786function MatrixScale3D(size: TPoint3D): TMatrix3D;
787begin
788 result := Matrix3D(size.x,0,0,0,
789 0,size.y,0,0,
790 0,0,size.z,0);
791end;
792
793function MatrixRotateX(angle: single): TMatrix3D;
794begin
795 result := Matrix3D( 1, 0, 0, 0,
796 0, cos(angle), sin(angle), 0,
797 0, -sin(angle), cos(angle), 0);
798end;
799
800function MatrixRotateY(angle: single): TMatrix3D;
801begin
802 result := Matrix3D( cos(angle), 0, -sin(angle), 0,
803 0, 1, 0, 0,
804 sin(angle), 0, cos(angle), 0);
805end;
806
807function MatrixRotateZ(angle: single): TMatrix3D;
808begin
809 result := Matrix3D( cos(angle), sin(angle), 0, 0,
810 -sin(angle), cos(angle), 0, 0,
811 0, 0, 1, 0);
812end;
813
814end.
815
Note: See TracBrowser for help on using the repository browser.