0001: // ----------------------------------------------------------------------------
0002: //
0003: // matrix.cpp - 行列計算
0004: // 
0005: // Copyright (c) 2002 今給黎 隆 (imagire@nify.com)
0006: // All Rights Reserved.
0007: //
0008: // ----------------------------------------------------------------------------
0009: #include <math.h>
0010: #include "matrix.h"
0011: 
0012: // ----------------------------------------------------------------------------
0013: // 行列計算
0014: // ----------------------------------------------------------------------------
0015: ifMatrix *ifMatrixIdentity( ifMatrix *pOut )
0016: {
0017:     int i, j;
0018:     
0019:     for(i=0;i<4;i++)
0020:         for(j=0;j<4;j++)
0021:             (*pOut)[i][j] = (i==j)?1.0f:0.0f;
0022:     
0023:     return pOut;
0024: }
0025: // ----------------------------------------------------------------------------
0026: ifMatrix* ifMatrixMultiply( ifMatrix *pOut,
0027:                             const ifMatrix *pM1,
0028:                             const ifMatrix *pM2
0029:                             )
0030: {
0031:     ifMatrix tmp;// (*pOut) とpM1もしくはpM2が等しかった時に間違えるので一時保存
0032:     int i, j;
0033:     
0034:     for(i=0;i<4;i++){
0035:         for(j=0;j<4;j++){
0036:             tmp[i][j] = (*pM1)[i][0]*(*pM2)[0][j]
0037:                       + (*pM1)[i][1]*(*pM2)[1][j]
0038:                       + (*pM1)[i][2]*(*pM2)[2][j]
0039:                       + (*pM1)[i][3]*(*pM2)[3][j];
0040:         }
0041:     }
0042:     for(i=0;i<4;i++){
0043:         for(j=0;j<4;j++){
0044:             (*pOut)[i][j] = tmp[i][j];
0045:         }
0046:     }
0047:     
0048:     return pOut;
0049: }
0050: // ----------------------------------------------------------------------------
0051: ifMatrix* ifMatrixRotationX( ifMatrix *pOut, float Angle )
0052: {
0053:     float c = (float)cos(Angle);
0054:     float s = (float)sin(Angle);
0055:     
0056:     (*pOut)[0][0] = 1.0f; (*pOut)[0][1] = 0.0f; (*pOut)[0][2] = 0.0f; (*pOut)[0][3] = 0.0f;
0057:     (*pOut)[1][0] = 0.0f; (*pOut)[1][1] =    c; (*pOut)[1][2] =    s; (*pOut)[1][3] = 0.0f;
0058:     (*pOut)[2][0] = 0.0f; (*pOut)[2][1] =   -s; (*pOut)[2][2] =    c; (*pOut)[2][3] = 0.0f;
0059:     (*pOut)[3][0] = 0.0f; (*pOut)[3][1] = 0.0f; (*pOut)[3][2] = 0.0f; (*pOut)[3][3] = 1.0f;
0060:     
0061:     return pOut;
0062: }
0063: // ----------------------------------------------------------------------------
0064: ifMatrix* ifMatrixRotationY( ifMatrix *pOut, float Angle )
0065: {
0066:     float c = (float)cos(Angle);
0067:     float s = (float)sin(Angle);
0068:     
0069:     (*pOut)[0][0] =    c; (*pOut)[0][1] = 0.0f; (*pOut)[0][2] =   -s; (*pOut)[0][3] = 0.0f;
0070:     (*pOut)[1][0] = 0.0f; (*pOut)[1][1] = 1.0f; (*pOut)[1][2] = 0.0f; (*pOut)[1][3] = 0.0f;
0071:     (*pOut)[2][0] =    s; (*pOut)[2][1] = 0.0f; (*pOut)[2][2] =    c; (*pOut)[2][3] = 0.0f;
0072:     (*pOut)[3][0] = 0.0f; (*pOut)[3][1] = 0.0f; (*pOut)[3][2] = 0.0f; (*pOut)[3][3] = 1.0f;
0073:     
0074:     return pOut;
0075: }
0076: // ----------------------------------------------------------------------------
0077: ifMatrix* ifMatrixRotationZ( ifMatrix *pOut, float Angle )
0078: {
0079:     float c = (float)cos(Angle);
0080:     float s = (float)sin(Angle);
0081:     
0082:     (*pOut)[0][0] =    c; (*pOut)[0][1] =    s; (*pOut)[0][2] = 0.0f; (*pOut)[0][3] = 0.0f;
0083:     (*pOut)[1][0] =   -s; (*pOut)[1][1] =    c; (*pOut)[1][2] = 0.0f; (*pOut)[1][3] = 0.0f;
0084:     (*pOut)[2][0] = 0.0f; (*pOut)[2][1] = 0.0f; (*pOut)[2][2] = 1.0f; (*pOut)[2][3] = 0.0f;
0085:     (*pOut)[3][0] = 0.0f; (*pOut)[3][1] = 0.0f; (*pOut)[3][2] = 0.0f; (*pOut)[3][3] = 1.0f;
0086:     
0087:     return pOut;
0088: }
0089: // ----------------------------------------------------------------------------
0090: ifMatrix* ifMatrixScaling( ifMatrix *pOut, float sx, float sy, float sz)
0091: {
0092:     (*pOut)[0][0] =   sx; (*pOut)[0][1] = 0.0f; (*pOut)[0][2] = 0.0f; (*pOut)[0][3] = 0.0f;
0093:     (*pOut)[1][0] = 0.0f; (*pOut)[1][1] =   sy; (*pOut)[1][2] = 0.0f; (*pOut)[1][3] = 0.0f;
0094:     (*pOut)[2][0] = 0.0f; (*pOut)[2][1] = 0.0f; (*pOut)[2][2] =   sz; (*pOut)[2][3] = 0.0f;
0095:     (*pOut)[3][0] = 0.0f; (*pOut)[3][1] = 0.0f; (*pOut)[3][2] = 0.0f; (*pOut)[3][3] = 1.0f;
0096:     
0097:     return pOut;
0098: }
0099: // ----------------------------------------------------------------------------
0100: ifMatrix* ifMatrixTranslation( ifMatrix *pOut, float x, float y, float z )
0101: {
0102:     (*pOut)[0][0] = 1.0f; (*pOut)[0][1] = 0.0f; (*pOut)[0][2] = 0.0f; (*pOut)[0][3] = 0.0f;
0103:     (*pOut)[1][0] = 0.0f; (*pOut)[1][1] = 1.0f; (*pOut)[1][2] = 0.0f; (*pOut)[1][3] = 0.0f;
0104:     (*pOut)[2][0] = 0.0f; (*pOut)[2][1] = 0.0f; (*pOut)[2][2] = 1.0f; (*pOut)[2][3] = 0.0f;
0105:     (*pOut)[3][0] =    x; (*pOut)[3][1] =    y; (*pOut)[3][2] =    z; (*pOut)[3][3] = 1.0f;
0106:     
0107:     return pOut;
0108: }
0109: // ----------------------------------------------------------------------------
0110: // 3次元の転置行列
0111: ifMatrix* ifMatrixTranspose( ifMatrix *pOut, const ifMatrix *pM )
0112: {
0113:     float m01 = (*pM)[0][1];
0114:     float m02 = (*pM)[0][2];
0115:     float m12 = (*pM)[1][2];
0116:     float m03 = (*pM)[0][3];
0117:     float m13 = (*pM)[1][3];
0118:     float m23 = (*pM)[2][3];
0119:     
0120:     (*pOut)[0][1] = (*pM)[1][0];
0121:     (*pOut)[0][2] = (*pM)[2][0];
0122:     (*pOut)[1][2] = (*pM)[2][1];
0123:     (*pOut)[0][3] = (*pM)[3][0];
0124:     (*pOut)[1][3] = (*pM)[3][1];
0125:     (*pOut)[2][3] = (*pM)[3][2];
0126:     (*pOut)[1][0] = m01;
0127:     (*pOut)[2][0] = m02;
0128:     (*pOut)[2][1] = m12;
0129:     (*pOut)[3][0] = m03;
0130:     (*pOut)[3][1] = m13;
0131:     (*pOut)[3][2] = m23;
0132:     (*pOut)[0][0] = (*pM)[0][0];
0133:     (*pOut)[1][1] = (*pM)[1][1];
0134:     (*pOut)[2][2] = (*pM)[2][2];
0135:     (*pOut)[3][3] = (*pM)[3][3];
0136:     
0137:     return pOut;
0138: }
0139: // ----------------------------------------------------------------------------
0140: 
0141: // ----------------------------------------------------------------------------
0142: // ベクトル計算
0143: // ----------------------------------------------------------------------------
0144: ifVector4* ifVec4Add( ifVector4* pOut
0145:                     , const ifVector4* pV1, const ifVector4* pV2)
0146: {
0147:     (*pOut)[0] = (*pV1)[0]+(*pV2)[0];
0148:     (*pOut)[1] = (*pV1)[1]+(*pV2)[1];
0149:     (*pOut)[2] = (*pV1)[2]+(*pV2)[2];
0150:     (*pOut)[3] = (*pV1)[3]+(*pV2)[3];
0151: 
0152:     return pOut;
0153: }
0154: // ----------------------------------------------------------------------------
0155: ifVector4* ifVec4Normalize( ifVector4 *pOut, const ifVector4 *pV )
0156: {
0157:     float rsq = 1.0f/(float)sqrt( (*pV)[0] * (*pV)[0]
0158:                                 + (*pV)[1] * (*pV)[1]
0159:                                 + (*pV)[2] * (*pV)[2]
0160:                                 + (*pV)[3] * (*pV)[3] );
0161:     (*pOut)[0] = (*pV)[0]*rsq;
0162:     (*pOut)[1] = (*pV)[1]*rsq;
0163:     (*pOut)[2] = (*pV)[2]*rsq;
0164:     (*pOut)[3] = (*pV)[3]*rsq;
0165: 
0166:     return pOut;
0167: }
0168: // ----------------------------------------------------------------------------
0169: ifVector4* ifVec4Transform( ifVector4 *pOut
0170:                     , const ifVector4 *pIn, const ifMatrix *pM )
0171: {
0172:     ifVector4 tmp;
0173: 
0174:     tmp[0] = (*pIn)[0]*(*pM)[0][0] + (*pIn)[1]*(*pM)[1][0] + (*pIn)[2]*(*pM)[2][0] + (*pIn)[3]*(*pM)[3][0];
0175:     tmp[1] = (*pIn)[0]*(*pM)[0][1] + (*pIn)[1]*(*pM)[1][1] + (*pIn)[2]*(*pM)[2][1] + (*pIn)[3]*(*pM)[3][1];
0176:     tmp[2] = (*pIn)[0]*(*pM)[0][2] + (*pIn)[1]*(*pM)[1][2] + (*pIn)[2]*(*pM)[2][2] + (*pIn)[3]*(*pM)[3][2];
0177:     tmp[3] = (*pIn)[0]*(*pM)[0][3] + (*pIn)[1]*(*pM)[1][3] + (*pIn)[2]*(*pM)[2][3] + (*pIn)[3]*(*pM)[3][3];
0178:     
0179:     (*pOut)[0] = tmp[0];
0180:     (*pOut)[1] = tmp[1];
0181:     (*pOut)[2] = tmp[2];
0182:     (*pOut)[3] = tmp[3];
0183: 
0184:     return pOut;
0185: }
0186: