GeometryTransferEngine : longベクトルと行列の乗算; 出力:longベクトル


GTE_LVMatrixMul();

この関数はlongベクトルに行列を掛けて、結果をlongベクトルで返します。

既知の公式です。

[GTEのコマンド]



オペコード: 0x41e012&0x49e012
入力: R11R122,R13R21,R22R23,R31R32,R33,IR1, IR2,IR3
出力: MAC0,MAC1,MAC2

よりよい理解のための擬似コード:
 R11R12 = (m.m[0][1]<<16) | m.m[0][0] ;
 R13R21 = (m.m[1][0]<<16) | m.m[0][2] ;
 R22R23 = (m.m[1][2]<<16) | m.m[1][1] ;
 R31R32 = (m.m[2][1]<<16) | m.m[2][0] ;
 R33    =  m.m[2][2]                    ;
 IR1    = vs->x >> 15 ;
 IR2    = vs->y >> 15 ;
 IR3    = vs->z >> 15 ;
// 非固定小数点(訳注:整数)のベクトル(IR1/IR2/IR3)と行列の乗算
                    // 結果は固定小数点
// Multiplication of non-fixed-point-vector(IR1/IR2/IR3) by matrix
                    // with result in fixed point .
 C2 0x41e012        
 var1 = MAC1 << 3 ; // << 12 << 3 = << 15 
 var2 = MAC2 << 3 ;
 var3 = MAC3 << 3 ;
 IR1    = vs->x & 0x7FFF ;
 IR2    = vs->y & 0x7FFF ;
 IR3    = vs->z & 0x7FFF ;
 
       // 固定小数点のベクトル(IR1/IR2/IR3)と行列の乗算
                    // 結果は固定小数点
       // Multiplication of fixed-point-vector(IR1/IR2/IR3) by matrix 
                   // with result in fixed point  
C2 0x49e012 
 
 vr->x = var1 + MAC1 ; 
 vr->y = var2 + MAC2 ; 
 vr->z = var3 + MAC3 ; 
動作するサンプルコード:
typedef struct
{
 long x,y,z ;
} VECTOR3 ;

typedef struct
{
 short m[3][3];
 long t[3];
} MATRIX ;

void GTE_LVMatrixMul (MATRIX *m,VECTOR3 *vs,VECTOR3 *vr)
{
asm
("
 # load matrix
 lw    $8,($4)
 lw    $9,0x4($4)
 lw    $10,0x8($4)
 lw    $11,0xC($4)
 lw    $12,0x10($4)
 # upload matrix
 ctc2  $8,$0            # R11R12 = m.m[0][1] m.m[0][0]
 ctc2  $9,$1            # R13R21 = m.m[1][0] m.m[0][2]
 ctc2  $10,$2           # R22R23 = m.m[1][2] m.m[1][1]
 ctc2  $11,$3           # R31R32 = m.m[2][1] m.m[2][0]
 ctc2  $12,$4           # R33    =           m.m[2][2]
 # get vector v1
 lw    $8,($5)
 lw    $9,0x4($5)
 lw    $10,0x8($5)
 # split coordinates
 sra   $11,$8,0xF
 andi  $8,$8,0x7FFF
 sra   $12,$9,0xF
 andi  $9,$9,0x7FFF
 sra   $13,$10,0xF
 andi  $10,$10,0x7FFF
 mtc2  $11,$9
 mtc2  $12,$10
 mtc2  $13,$11
 nop
 nop
 
 c2    0x41e012
 # get first result
 mfc2  $11,$25
 mfc2  $12,$26
 mfc2  $13,$27
 mtc2  $8,$9
 mtc2  $9,$10
 mtc2  $10,$11
 nop
 nop
 
 c2    0x49e012
 sll   $11,$11,0x3
 sll   $12,$12,0x3
 sll   $13,$13,0x3
 # get second result
 mfc2  $8,$25
 mfc2  $9,$26
 mfc2  $10,$27
 # put it together
 addu  $8,$8,$11
 addu  $9,$9,$12
 addu  $10,$10,$13
 # write back
 sw    $8,($6)
 sw    $9,0x4($6)
 sw    $10,0x8($6)
");
}
[開く] "Coding & Hacking"-サイトに戻る  1