0001: #include "stdafx.h"
0002: #include "math.h"
0003: #include "render.h"
0004: 
0005: namespace Render {
0006: 
0007: // 背景色
0008: D3DXVECTOR3 BG_COLOR = D3DXVECTOR3(0.25f, 0.4f, 0.5f);
0009: 
0010: class CCamera
0011: {
0012: private:
0013:     D3DXMATRIX  m_mView;
0014:     D3DXMATRIX  m_mProj;
0015:     D3DXMATRIX  m_mVP;
0016:     D3DXMATRIX  m_mVP_Inv;
0017:     D3DXMATRIX  m_mView_Inv;
0018: 
0019:     D3DXVECTOR3 m_vFrom;
0020:     D3DXVECTOR3 m_vLookat;
0021:     D3DXVECTOR3 m_vUp;
0022: 
0023:     float   m_fFovy;
0024:     float   m_fAspect;
0025:     float   m_fNear;
0026:     float   m_fFar;
0027: 
0028: public:
0029: 
0030:     void Update();
0031:     void SetFrom  (const D3DXVECTOR3 *p){m_vFrom  =*p;}
0032:     void SetLookAt(const D3DXVECTOR3 *p){m_vLookat=*p;}
0033:     void SetUp    (const D3DXVECTOR3 *p){m_vUp    =*p;}
0034:     void SetFovY  (float val){m_fFovy   = val;}
0035:     void SetAspect(float val){m_fAspect = val;}
0036:     void SetNear  (float val){m_fNear   = val;}
0037:     void SetFar   (float val){m_fFar    = val;}
0038: 
0039:     inline const D3DXMATRIX *GetViewInverse() const {return &m_mView_Inv;}
0040:     inline const D3DXMATRIX *GetViewProjInverse() const {return &m_mVP_Inv;}
0041:     inline void GetFrom (D3DXVECTOR3 *dest) const {*dest = m_vFrom;}
0042: };
0043: 
0044: // ---------------------------------------------------------------------------
0045: // オブジェクト
0046: // ---------------------------------------------------------------------------
0047: char s_data[4*RENDER_WIDTH*RENDER_HEIGHT];// 仮想フレームバッファ
0048: CCamera camera;
0049: CTriangle  room[12];    // 部屋
0050: CTriangle  blocks[10];  // 低い箱
0051: CTriangle  blockt[10];  // 高い箱
0052: CSphere sphere;         // 低いところにある玉
0053: CSphere tphere;         // 高いところにある玉
0054: 
0055: // ---------------------------------------------------------------------------
0056: // 玉
0057: OBJ_DATA sphere_data[] = {
0058: {// 小さいのに乗ってるほう
0059:     OBJ_TYPE_SPHERE,
0060:     {
0061:         {0.01f, 0.05f, 0.02f },
0062:         {0.01f, 0.05f, 0.02f },
0063:         {0.10f, 0.10f, 0.10f },
0064:         16.0f,
0065:     },{{0,0,0},{0,0,0},{0,0,0}},{
0066:         {185.5, 165+100,169},
0067:         100.0f,
0068:     }
0069: },{// 大きいのに乗ってるほう
0070:     OBJ_TYPE_SPHERE,
0071:     {
0072:         {0.02f, 0.01f, 0.05f},
0073:         {0.02f, 0.01f, 0.05f},
0074:         {0.10f, 0.10f, 0.10f },
0075:         8.0f,
0076:     },{{0,0,0},{0,0,0},{0,0,0}},{
0077:         {368.5, 330+100,351},
0078:         100.0f,
0079:     }
0080: }};
0081: // ---------------------------------------------------------------------------
0082: // 部屋
0083: OBJ_DATA room_data[12] = {
0084: {// ライト1
0085:     OBJ_TYPE_TRIANGLE,
0086:     {
0087:         {100.0f, 100.0f, 100.0f},
0088:         {  0.0f,   0.0f,   0.0f},
0089:         {  0.0f,   0.0f,   0.0f},
0090:         0.0f,
0091:     },{
0092:         {213.0, 548.799f, 227.0},
0093:         {213.0, 548.799f, 332.0},
0094:         {343.0, 548.799f, 227.0},
0095:     }
0096: },{// ライト2
0097:     OBJ_TYPE_TRIANGLE,
0098:     {
0099:         {100.0f, 100.0f, 100.0f},
0100:         {  0.0f,   0.0f,   0.0f},
0101:         {  0.0f,   0.0f,   0.0f},
0102:         0.0f,
0103:     },{
0104:         {343.0, 548.799f, 227.0},
0105:         {213.0, 548.799f, 332.0},
0106:         {343.0, 548.799f, 332.0},
0107:     }
0108: },{// 左1
0109:     OBJ_TYPE_TRIANGLE,
0110:     {
0111:         {0.05f, 0.01f, 0.01f},
0112:         {0.05f, 0.01f, 0.01f},
0113:         {0.00f, 0.00f, 0.00f},
0114:         32.0f,
0115:     },{
0116:         {552.8f,   0.0f,   0.0f},
0117:         {556.0f, 548.8f,   0.0f},
0118:         {549.6f,   0.0f, 559.2f},
0119:     }
0120: 
0121: },{// 左2
0122:     OBJ_TYPE_TRIANGLE,
0123:     {
0124:         {0.05f, 0.01f, 0.01f},
0125:         {0.05f, 0.01f, 0.01f},
0126:         {0.00f, 0.00f, 0.00f},
0127:         32.0f,
0128:     },{
0129:         {549.6f,   0.0f, 559.2f},
0130:         {556.0f, 548.8f,   0.0f},
0131:         {556.0f, 548.8f, 559.2f},
0132:     }
0133: 
0134: },{// 右1
0135:     OBJ_TYPE_TRIANGLE,
0136:     {
0137:         {0.01f, 0.01f, 0.05f},
0138:         {0.01f, 0.01f, 0.05f},
0139:         {0.00f, 0.00f, 0.00f},
0140:         32.0f,
0141:     },{
0142:         {0.0f,   0.0f,   0.0f},
0143:         {0.0f,   0.0f, 559.2f},
0144:         {0.0f, 548.8f,   0.0f},
0145:     }
0146: 
0147: },{// 右2
0148:     OBJ_TYPE_TRIANGLE,
0149:     {
0150:         {0.01f, 0.01f, 0.05f},
0151:         {0.01f, 0.01f, 0.05f},
0152:         {0.00f, 0.00f, 0.00f},
0153:         32.0f,
0154:     },{
0155:         {0.0f, 548.8f,   0.0f},
0156:         {0.0f,   0.0f, 559.2f},
0157:         {0.0f, 548.8f, 559.2f},
0158:     }
0159: 
0160: },{// 奥1
0161:     OBJ_TYPE_TRIANGLE,
0162:     {
0163:         {0.05f, 0.05f, 0.05f},
0164:         {0.05f, 0.05f, 0.05f},
0165:         {0.00f, 0.00f, 0.00f},
0166:         32.0f,
0167:     },{
0168:         {  0.0f,   0.0f, 559.2f},
0169:         {549.6f,   0.0f, 559.2f},
0170:         {  0.0f, 548.8f, 559.2f},
0171:     }
0172: 
0173: },{// 奥2
0174:     OBJ_TYPE_TRIANGLE,
0175:     {
0176:         {0.05f, 0.05f, 0.05f},
0177:         {0.05f, 0.05f, 0.05f},
0178:         {0.00f, 0.00f, 0.00f},
0179:         32.0f,
0180:     },{
0181:         {  0.0f, 548.8f, 559.2f},
0182:         {549.6f,   0.0f, 559.2f},
0183:         {556.0f, 548.8f, 559.2f},
0184:     }
0185: 
0186: },{// 天井1
0187:     OBJ_TYPE_TRIANGLE,
0188:     {
0189:         {0.05f, 0.05f, 0.05f},
0190:         {0.05f, 0.05f, 0.05f},
0191:         {0.00f, 0.00f, 0.00f},
0192:         32.0f,
0193:     },{
0194:         {  0.0f, 548.8f,   0.0f},
0195:         {  0.0f, 548.8f, 559.2f},
0196:         {556.0f, 548.8f,   0.0f},
0197:     }
0198: 
0199: },{// 天井2
0200:     OBJ_TYPE_TRIANGLE,
0201:     {
0202:         {0.05f, 0.05f, 0.05f},
0203:         {0.05f, 0.05f, 0.05f},
0204:         {0.00f, 0.00f, 0.00f},
0205:         32.0f,
0206:     },{
0207:         {  0.0f, 548.8f, 559.2f},
0208:         {556.0f, 548.8f, 559.2f},
0209:         {556.0f, 548.8f,   0.0f},
0210:     }
0211: 
0212: },{// 床1
0213:     OBJ_TYPE_TRIANGLE,
0214:     {
0215:         {0.05f, 0.05f, 0.05f},
0216:         {0.05f, 0.05f, 0.05f},
0217:         {0.00f, 0.00f, 0.00f},
0218:         32.0f,
0219:     },{
0220:         {  0.0f, 0.0f,   0.0f},
0221:         {552.8f, 0.0f,   0.0f},
0222:         {  0.0f, 0.0f, 559.2f},
0223:     }
0224: },{// 床1
0225:     OBJ_TYPE_TRIANGLE,
0226:     {
0227:         {0.05f, 0.05f, 0.05f},
0228:         {0.05f, 0.05f, 0.05f},
0229:         {0.00f, 0.00f, 0.00f},
0230:         32.0f,
0231:     },{
0232:         {  0.0f, 0.0f, 559.2f},
0233:         {552.8f, 0.0f,   0.0f},
0234:         {549.6f, 0.0f, 559.2f},
0235:     }
0236: }};
0237: 
0238: // ---------------------------------------------------------------------------
0239: // 低い箱
0240: OBJ_DATA Short_block[] = {
0241: {
0242:     // 床
0243:     OBJ_TYPE_TRIANGLE,
0244:     {
0245:         {0.05f, 0.05f, 0.05f},
0246:         {0.05f, 0.05f, 0.05f},
0247:         {0.00f, 0.00f, 0.00f},
0248:         32.0f,
0249:     },{
0250:         { 82.0f, 165.0f, 225.0f},
0251:         {130.0f, 165.0f,  65.0f},
0252:         {240.0f, 165.0f, 272.0f},
0253:     }
0254: },{
0255:     OBJ_TYPE_TRIANGLE,
0256:     {
0257:         {0.05f, 0.05f, 0.05f},
0258:         {0.05f, 0.05f, 0.05f},
0259:         {0.00f, 0.00f, 0.00f},
0260:         32.0f,
0261:     },{
0262:         {290.0, 165.0, 114.0},
0263:         {240.0, 165.0, 272.0},
0264:         {130.0, 165.0,  65.0},
0265:     }
0266: },{//側面
0267:     OBJ_TYPE_TRIANGLE,
0268:     {
0269:         {0.05f, 0.05f, 0.05f},
0270:         {0.05f, 0.05f, 0.05f},
0271:         {0.00f, 0.00f, 0.00f},
0272:         32.0f,
0273:     },{
0274:         {290.0, 165.0, 114.0},
0275:         {290.0,   0.0, 114.0},
0276:         {240.0, 165.0, 272.0},
0277:     }
0278: },{
0279:     OBJ_TYPE_TRIANGLE,
0280:     {
0281:         {0.05f, 0.05f, 0.05f},
0282:         {0.05f, 0.05f, 0.05f},
0283:         {0.00f, 0.00f, 0.00f},
0284:         32.0f,
0285:     },{
0286:         {240.0, 165.0, 272.0},
0287:         {290.0,   0.0, 114.0},
0288:         {240.0,   0.0, 272.0},
0289:     }
0290: },{//前面
0291:     OBJ_TYPE_TRIANGLE,
0292:     {
0293:         {0.05f, 0.05f, 0.05f},
0294:         {0.05f, 0.05f, 0.05f},
0295:         {0.00f, 0.00f, 0.00f},
0296:         32.0f,
0297:     },{
0298:         {290.0,   0.0, 114.0},
0299:         {290.0, 165.0, 114.0},
0300:         {130.0,   0.0,  65.0},
0301:     }
0302: },{
0303:     OBJ_TYPE_TRIANGLE,
0304:     {
0305:         {0.05f, 0.05f, 0.05f},
0306:         {0.05f, 0.05f, 0.05f},
0307:         {0.00f, 0.00f, 0.00f},
0308:         32.0f,
0309:     },{
0310:         {130.0,   0.0,  65.0},
0311:         {290.0, 165.0, 114.0},
0312:         {130.0, 165.0,  65.0},
0313:     }
0314: },{//側面
0315:     OBJ_TYPE_TRIANGLE,
0316:     {
0317:         {0.05f, 0.05f, 0.05f},
0318:         {0.05f, 0.05f, 0.05f},
0319:         {0.00f, 0.00f, 0.00f},
0320:         32.0f,
0321:     },{
0322:         { 82.0,   0.0, 225.0},
0323:         {130.0, 165.0,  65.0},
0324:         { 82.0, 165.0, 225.0},
0325:     }
0326: },{
0327:     OBJ_TYPE_TRIANGLE,
0328:     {
0329:         {0.05f, 0.05f, 0.05f},
0330:         {0.05f, 0.05f, 0.05f},
0331:         {0.00f, 0.00f, 0.00f},
0332:         32.0f,
0333:     },{
0334:         { 82.0,   0.0, 225.0},
0335:         {130.0,   0.0,  65.0},
0336:         {130.0, 165.0,  65.0},
0337:     }
0338: },{//背面
0339:     OBJ_TYPE_TRIANGLE,
0340:     {
0341:         {0.05f, 0.05f, 0.05f},
0342:         {0.05f, 0.05f, 0.05f},
0343:         {0.00f, 0.00f, 0.00f},
0344:         32.0f,
0345:     },{
0346:         {240.0,   0.0, 272.0},
0347:         { 82.0, 165.0, 225.0},
0348:         {240.0, 165.0, 272.0},
0349:     }
0350: },{
0351:     OBJ_TYPE_TRIANGLE,
0352:     {
0353:         {0.05f, 0.05f, 0.05f},
0354:         {0.05f, 0.05f, 0.05f},
0355:         {0.00f, 0.00f, 0.00f},
0356:         32.0f,
0357:     },{
0358:         {240.0,   0.0, 272.0},
0359:         { 82.0,   0.0, 225.0},
0360:         { 82.0, 165.0, 225.0},
0361:     }
0362: }};
0363: 
0364: // ---------------------------------------------------------------------------
0365: // 高い箱
0366: OBJ_DATA Tall_block[] = {
0367: {
0368:     // 床
0369:     OBJ_TYPE_TRIANGLE,
0370:     {
0371:         {0.05f, 0.05f, 0.05f},
0372:         {0.05f, 0.05f, 0.05f},
0373:         {0.00f, 0.00f, 0.00f},
0374:         32.0f,
0375:     },{
0376:         {423.0f, 330.0f, 247.0f},
0377:         {314.0f, 330.0f, 456.0f},
0378:         {265.0f, 330.0f, 296.0f},
0379:     }
0380: },{
0381:     OBJ_TYPE_TRIANGLE,
0382:     {
0383:         {0.05f, 0.05f, 0.05f},
0384:         {0.05f, 0.05f, 0.05f},
0385:         {0.00f, 0.00f, 0.00f},
0386:         32.0f,
0387:     },{
0388:         {423.0f, 330.0f, 247.0f},
0389:         {472.0f, 330.0f, 406.0f},
0390:         {314.0f, 330.0f, 456.0f},
0391:     }
0392: },{//側面
0393:     OBJ_TYPE_TRIANGLE,
0394:     {
0395:         {0.05f, 0.05f, 0.05f},
0396:         {0.05f, 0.05f, 0.05f},
0397:         {0.00f, 0.00f, 0.00f},
0398:         32.0f,
0399:     },{
0400:         {423.0f,   0.0f, 247.0f},
0401:         {472.0f,   0.0f, 406.0f},
0402:         {423.0f, 330.0f, 247.0f},
0403:     }
0404: },{
0405:     OBJ_TYPE_TRIANGLE,
0406:     {
0407:         {0.05f, 0.05f, 0.05f},
0408:         {0.05f, 0.05f, 0.05f},
0409:         {0.00f, 0.00f, 0.00f},
0410:         32.0f,
0411:     },{
0412:         {423.0f, 330.0f, 247.0f},
0413:         {472.0f,   0.0f, 406.0f},
0414:         {472.0f, 330.0f, 406.0f},
0415:     }
0416: },{//背面
0417:     OBJ_TYPE_TRIANGLE,
0418:     {
0419:         {0.05f, 0.05f, 0.05f},
0420:         {0.05f, 0.05f, 0.05f},
0421:         {0.00f, 0.00f, 0.00f},
0422:         32.0f,
0423:     },{
0424:         {314.0f,   0.0f, 456.0f},
0425:         {314.0f, 330.0f, 456.0f},
0426:         {472.0f,   0.0f, 406.0f},
0427:     }
0428: },{
0429:     OBJ_TYPE_TRIANGLE,
0430:     {
0431:         {0.05f, 0.05f, 0.05f},
0432:         {0.05f, 0.05f, 0.05f},
0433:         {0.00f, 0.00f, 0.00f},
0434:         32.0f,
0435:     },{
0436:         {314.0f, 330.0f, 456.0f},
0437:         {472.0f, 330.0f, 406.0f},
0438:         {472.0f,   0.0f, 406.0f},
0439:     }
0440: },{//側面
0441:     OBJ_TYPE_TRIANGLE,
0442:     {
0443:         {0.05f, 0.05f, 0.05f},
0444:         {0.05f, 0.05f, 0.05f},
0445:         {0.00f, 0.00f, 0.00f},
0446:         32.0f,
0447:     },{
0448:         {314.0f,   0.0f, 456.0f},
0449:         {265.0f,   0.0f, 296.0f},
0450:         {265.0f, 330.0f, 296.0f},
0451:     }
0452: },{
0453:     OBJ_TYPE_TRIANGLE,
0454:     {
0455:         {0.05f, 0.05f, 0.05f},
0456:         {0.05f, 0.05f, 0.05f},
0457:         {0.00f, 0.00f, 0.00f},
0458:         32.0f,
0459:     },{
0460:         {314.0f,   0.0f, 456.0f},
0461:         {265.0f, 330.0f, 296.0f},
0462:         {314.0f, 330.0f, 456.0f},
0463:     }
0464: },{//前面
0465:     OBJ_TYPE_TRIANGLE,
0466:     {
0467:         {0.05f, 0.05f, 0.05f},
0468:         {0.05f, 0.05f, 0.05f},
0469:         {0.00f, 0.00f, 0.00f},
0470:         32.0f,
0471:     },{
0472:         {265.0f,   0.0f, 296.0f},
0473:         {423.0f,   0.0f, 247.0f},
0474:         {265.0f, 330.0f, 296.0f},
0475:     }
0476: },{
0477:     OBJ_TYPE_TRIANGLE,
0478:     {
0479:         {0.05f, 0.05f, 0.05f},
0480:         {0.05f, 0.05f, 0.05f},
0481:         {0.00f, 0.00f, 0.00f},
0482:         32.0f,
0483:     },{
0484:         {265.0f, 330.0f, 296.0f},
0485:         {423.0f,   0.0f, 247.0f},
0486:         {423.0f, 330.0f, 247.0f},
0487:     }
0488: }};
0489: 
0490: // ---------------------------------------------------------------------------
0491: // 関数宣言
0492: // ---------------------------------------------------------------------------
0493: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y);
0494: 
0495: 
0496: // ---------------------------------------------------------------------------
0497: // カメラクラス
0498: // ---------------------------------------------------------------------------
0499: void CCamera::Update()
0500: {
0501:     D3DXMatrixLookAtLH( &m_mView, &m_vFrom, &m_vLookat, &m_vUp );
0502:     D3DXMatrixPerspectiveFovLH( &m_mProj, m_fFovy, m_fAspect, m_fNear, m_fFar );
0503:     m_mVP = m_mView * m_mProj;
0504: 
0505:     D3DXMatrixInverse( &m_mView_Inv, NULL, &m_mView);
0506:     D3DXMatrixInverse( &m_mVP_Inv, NULL, &m_mVP);
0507: }
0508: // ---------------------------------------------------------------------------
0509: char *GetDataPointer()
0510: {
0511:     return s_data;
0512: }
0513: // ---------------------------------------------------------------------------
0514: void Init()
0515: {
0516:     int i,j;
0517: 
0518:     // フレームバッファの初期化
0519:     for(j=0;j<RENDER_HEIGHT;j++){
0520:     for(i=0;i<RENDER_WIDTH ;i++){
0521:         s_data[4*(j*RENDER_WIDTH+i)+0]=(char)255;// R
0522:         s_data[4*(j*RENDER_WIDTH+i)+1]=(char)(i*256/RENDER_WIDTH );// G
0523:         s_data[4*(j*RENDER_WIDTH+i)+2]=(char)(j*256/RENDER_HEIGHT);// B
0524:     }
0525:     }
0526:     
0527:     // カメラの設定
0528:     camera.SetFrom  (&D3DXVECTOR3(278,273,-800));
0529:     camera.SetLookAt(&D3DXVECTOR3(278,273,0));
0530:     camera.SetUp    (&D3DXVECTOR3(0,1,0));
0531:     camera.SetFovY  (D3DX_PI/4);
0532:     camera.SetAspect(1.0f);
0533:     camera.SetNear  (0.01f);
0534:     camera.SetFar   (100.0f);
0535:     camera.Update();
0536: 
0537:     // オブジェクトの初期化
0538:     sphere.Init(&sphere_data[0]);
0539:     tphere.Init(&sphere_data[1]);
0540:     for(i=0;i<12;i++){
0541:         room[i].Init(&room_data[i]);
0542:     }
0543:     for(i=0;i<10;i++){
0544:         blocks[i].Init(&Short_block[i]);
0545:     }
0546:     for(i=0;i<10;i++){
0547:         blockt[i].Init(&Tall_block[i]);
0548:     }
0549: }
0550: // ---------------------------------------------------------------------------
0551: void Delete()
0552: {
0553: }
0554: // ---------------------------------------------------------------------------
0555: void Render()
0556: {
0557:     for(int j=0;j<RENDER_HEIGHT;j++){
0558:     for(int i=0;i<RENDER_WIDTH ;i++){
0559:         D3DXVECTOR3 col;
0560:         GetColor(&col, ((float)i+0.5f)/(float)RENDER_WIDTH
0561:                      , ((float)j+0.5f)/(float)RENDER_HEIGHT);
0562:         s_data[4*(j*RENDER_WIDTH+i)+0]=(char)(255.9*min(1,col.x));// R
0563:         s_data[4*(j*RENDER_WIDTH+i)+1]=(char)(255.9*min(1,col.y));// G
0564:         s_data[4*(j*RENDER_WIDTH+i)+2]=(char)(255.9*min(1,col.z));// B
0565:     }
0566:     }
0567: }
0568: 
0569: // ---------------------------------------------------------------------------
0570: // 基本オブジェクト
0571: // ---------------------------------------------------------------------------
0572: void CObject::Init(OBJ_DATA *pData)
0573: {
0574:     m_type=pData->type;
0575: 
0576:     this->m_material = pData->material;
0577: }
0578: // ---------------------------------------------------------------------------
0579: D3DXVECTOR3 *CObject::GetColor(D3DXVECTOR3 *dest, float LN, float HN )
0580: {
0581:     *dest = *(D3DXVECTOR3*)&this->m_material.COLOR_AMB
0582:           + *(D3DXVECTOR3*)&this->m_material.COLOR_DIF * LN
0583:           + *(D3DXVECTOR3*)&this->m_material.COLOR_SPE * powf(HN, this->m_material.speq_power);
0584: 
0585:     return dest;
0586: }
0587: // ---------------------------------------------------------------------------
0588: // 球
0589: // ---------------------------------------------------------------------------
0590: CSphere::CSphere()
0591: {
0592: }
0593: // ---------------------------------------------------------------------------
0594: void CSphere::Init(OBJ_DATA *pData)
0595: {
0596:     ((CObject*)this)->Init(pData);
0597: 
0598:     this->center.x = pData->sphere.center[0];
0599:     this->center.y = pData->sphere.center[1];
0600:     this->center.z = pData->sphere.center[2];
0601: 
0602:     radius_sq = pData->sphere.radius;
0603:     radius_sq *= radius_sq;
0604: }
0605: // ---------------------------------------------------------------------------
0606: float CSphere::IsAcross(D3DXVECTOR4 *n, D3DXVECTOR4 *p, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0607: {
0608:     FLOAT t, tp, tn;
0609: 
0610:     // 線分との判定
0611: 
0612:     D3DXVECTOR4 xc = (*x)-center;
0613:     FLOAT xc2 = D3DXVec3Dot((D3DXVECTOR3 *)&xc, (D3DXVECTOR3 *)&xc);
0614:     FLOAT vxc = D3DXVec3Dot((D3DXVECTOR3 *)v, (D3DXVECTOR3 *)&xc);
0615:     FLOAT D = sqrtf(vxc*vxc-xc2+radius_sq);
0616:     
0617:     if(D<0) return -INFINTY_DIST;
0618: 
0619:     tp = -vxc+D;
0620:     tn = -vxc-D;
0621: 
0622:     if(tn<0){
0623:         if(tp<0) return -INFINTY_DIST;
0624:         t = tp;
0625:     }else{
0626:         t = tn;
0627:     }
0628: 
0629:     *p = (*x)+t*(*v);
0630:     *n = *p-center;
0631:     D3DXVec3Normalize((D3DXVECTOR3*)n, (D3DXVECTOR3*)n);
0632: 
0633:     return t;
0634: }
0635: 
0636: // ---------------------------------------------------------------------------
0637: // 3角形
0638: // ---------------------------------------------------------------------------
0639: CTriangle::CTriangle()
0640: {
0641: }
0642: // ---------------------------------------------------------------------------
0643: void CTriangle::Init(OBJ_DATA *pData)
0644: {
0645:     ((CObject*)this)->Init(pData);
0646: 
0647:     this->pos[0] = D3DXVECTOR4( pData->triangle.x0[0],
0648:                                 pData->triangle.x0[1],
0649:                                 pData->triangle.x0[2],
0650:                                 1.0f);
0651:     this->pos[1] = D3DXVECTOR4( pData->triangle.x1[0],
0652:                                 pData->triangle.x1[1],
0653:                                 pData->triangle.x1[2],
0654:                                 1.0f);
0655:     this->pos[2] = D3DXVECTOR4( pData->triangle.x2[0],
0656:                                 pData->triangle.x2[1],
0657:                                 pData->triangle.x2[2],
0658:                                 1.0f);
0659: 
0660:     // 法線ベクトルの計算
0661:     D3DXVECTOR4 t0 = this->pos[1]-this->pos[0];
0662:     D3DXVECTOR4 t1 = this->pos[2]-this->pos[0];
0663:     D3DXVec3Cross((D3DXVECTOR3*)&normal, (D3DXVECTOR3*)&t1, (D3DXVECTOR3*)&t0);
0664:     D3DXVec3Normalize((D3DXVECTOR3*)&normal, (D3DXVECTOR3*)&normal);
0665:     normal.w = 0;
0666: }
0667: // ---------------------------------------------------------------------------
0668: float CTriangle::IsAcross(D3DXVECTOR4 *n, D3DXVECTOR4 *p, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0669: {
0670:     FLOAT t;
0671: 
0672:     // 線分との判定
0673:     D3DXVECTOR4 xp = this->pos[0]-(*x);
0674: 
0675:     FLOAT xpn = D3DXVec3Dot((D3DXVECTOR3 *)&xp, (D3DXVECTOR3 *)&normal);
0676:     FLOAT vn  = D3DXVec3Dot((D3DXVECTOR3 *)v, (D3DXVECTOR3 *)&normal);
0677:     
0678:     if(-0.00001f<=vn)return -INFINTY_DIST;// カリングと無限大を外す
0679: 
0680:     t = xpn/vn;
0681:     
0682:     if(t<0) return -INFINTY_DIST;// 後ろ向きのレイは無効
0683: 
0684:     *p = (*x)+t*(*v);
0685:     *n = normal;
0686: 
0687:     D3DXVECTOR4 d0, d1;
0688:     D3DXVECTOR3 c;
0689:     d0 = (*p)-this->pos[0];
0690:     d1 = this->pos[1]-this->pos[0];
0691:     D3DXVec3Cross(&c, (D3DXVECTOR3*)&d1, (D3DXVECTOR3*)&d0);
0692:     if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)>0)return -INFINTY_DIST;
0693:     d0 = (*p)-this->pos[1];
0694:     d1 = this->pos[2]-this->pos[1];
0695:     D3DXVec3Cross(&c, (D3DXVECTOR3*)&d1, (D3DXVECTOR3*)&d0);
0696:     if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)>0)return -INFINTY_DIST;
0697:     d0 = (*p)-this->pos[2];
0698:     d1 = this->pos[0]-this->pos[2];
0699:     D3DXVec3Cross(&c, (D3DXVECTOR3*)&d1, (D3DXVECTOR3*)&d0);
0700:     if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)>0)return -INFINTY_DIST;
0701:     
0702:     return t;
0703: }
0704: 
0705: 
0706: // ---------------------------------------------------------------------------
0707: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, D3DXVECTOR4 *x, D3DXVECTOR4 *v)
0708: {
0709:     D3DXVECTOR4 light_pos   = D3DXVECTOR4(278.f, 548.8f, 279.5f,1);// 光源の位置
0710:     D3DXVECTOR3 light_color = D3DXVECTOR3( 10.f,   9.0f,   5.0f);  // 光源の色
0711: 
0712:     float ttmp;
0713:     D3DXVECTOR4 ptmp;
0714:     D3DXVECTOR4 ntmp;
0715:     int i;
0716:     
0717:     float t = CObject::INFINTY_DIST;    // 最近接オブジェクトとの距離
0718:     D3DXVECTOR4 p;                      // 最近接点
0719:     D3DXVECTOR4 n;                      // 最近接点での法線
0720:     CObject *pObj = NULL;               // 最近接オブジェクト
0721: 
0722:     // 一番近くにあるオブジェクトを検索する
0723:     ttmp = sphere.IsAcross(&ntmp, &ptmp, x, v);
0724:     if(0<=ttmp && ttmp<t){
0725:         t = ttmp;
0726:         n = ntmp;
0727:         p = ptmp;
0728:         pObj = &sphere;
0729:     }
0730:     ttmp = tphere.IsAcross(&ntmp, &ptmp, x, v);
0731:     if(0<=ttmp && ttmp<t){
0732:         t = ttmp;
0733:         n = ntmp;
0734:         p = ptmp;
0735:         pObj = &tphere;
0736:     }
0737:     for(i = 0; i<12; i++){
0738:         ttmp = room[i].IsAcross(&ntmp, &ptmp, x, v);
0739:         if(0<=ttmp && ttmp<t){
0740:             t = ttmp;
0741:             n = ntmp;
0742:             p = ptmp;
0743:             pObj = &room[i];
0744:         }
0745:     }
0746: 
0747:     for(i = 0; i<10; i++){
0748:         ttmp = blocks[i].IsAcross(&ntmp, &ptmp, x, v);
0749:         if(0<=ttmp && ttmp<t){
0750:             t = ttmp;
0751:             n = ntmp;
0752:             p = ptmp;
0753:             pObj = &blocks[i];
0754:         }
0755:     }
0756:     for(i = 0; i<10; i++){
0757:         ttmp = blockt[i].IsAcross(&ntmp, &ptmp, x, v);
0758:         if(0<=ttmp && ttmp<t){
0759:             t = ttmp;
0760:             n = ntmp;
0761:             p = ptmp;
0762:             pObj = &blockt[i];
0763:         }
0764:     }
0765: 
0766: 
0767:     if( pObj ){
0768:         // 当たり
0769:         
0770:         // オブジェクトの色をPhongの鏡面反射で計算する
0771:         D3DXVECTOR4 l = light_pos-p;
0772:         float L2 = D3DXVec3Dot((D3DXVECTOR3 *)&l, (D3DXVECTOR3 *)&l);
0773:         D3DXVec3Normalize((D3DXVECTOR3 *)&l, (D3DXVECTOR3 *)&l);
0774: 
0775:         D3DXVECTOR3 dir, H;
0776:         // 視線の計算
0777:         camera.GetFrom(&dir);
0778:         dir = dir - *(D3DXVECTOR3 *)&p;
0779:         D3DXVec3Normalize(&dir, &dir);
0780:         // ハーフベクトル
0781:         H = dir+*(D3DXVECTOR3 *)&l;
0782:         D3DXVec3Normalize((D3DXVECTOR3 *)&H, (D3DXVECTOR3 *)&H);
0783: 
0784:         float LN = D3DXVec3Dot((D3DXVECTOR3 *)&l, (D3DXVECTOR3 *)&n);
0785:         float HN = D3DXVec3Dot((D3DXVECTOR3 *)&H, (D3DXVECTOR3 *)&n);
0786:         if(LN<0) LN=0;
0787:         if(HN<0) HN=0;
0788: 
0789:         pObj->GetColor(dest, LN, HN);
0790:         
0791:         // 光源の色の反映
0792:         dest->x *= light_color.x;
0793:         dest->y *= light_color.y;
0794:         dest->z *= light_color.z;
0795:         
0796:         // 光の強さの適当な補正
0797:         *dest *= min(1.5f, 500000.0f/(10000.0f+L2)); // 距離による補正
0798:         *dest *= min(1, l.y+0.1f);                  // 光の向きをcosθの関数にする
0799:         
0800:     }else{
0801:         // 外れ
0802:         *dest = BG_COLOR;
0803:     }
0804: 
0805: 
0806:     return dest;
0807: }
0808: // ---------------------------------------------------------------------------
0809: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y)
0810: {
0811:     D3DXVECTOR4 ray_start_proj = D3DXVECTOR4(-2*x+1, -2*y+1, 0, 1);// 前方クリップ面
0812:     D3DXVECTOR4 ray_eye        = D3DXVECTOR4(0, 0, 0, 1);// ビュー空間でのカメラの位置
0813:     D3DXVECTOR4 ray_start;
0814:     D3DXVECTOR4 ray_to;
0815:     D3DXVECTOR4 ray_dir;
0816:     D3DXMATRIX mInv;
0817:     
0818:     // 視点を射影空間からワールド座標に変換する
0819:     D3DXVec4Transform( &ray_start, &ray_eye,        camera.GetViewInverse() );
0820:     D3DXVec4Transform( &ray_to,    &ray_start_proj, camera.GetViewProjInverse() );
0821:     D3DXVec4Scale( &ray_to,    &ray_to,    1.0f/ray_to.w   );// w=1 の射影空間に落とす
0822:     // 向きの計算
0823:     ray_dir = ray_to - ray_start;
0824:     D3DXVec4Normalize(&ray_dir, &ray_dir);
0825:     
0826:     // 色計算
0827:     return GetColor(dest, &ray_start, &ray_dir);
0828: }
0829: 
0830: };// namespace Render
0831: