Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

647 lines
20 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: Dolphin.cpp
  3. //
  4. // Desc: Sample of swimming dolphin
  5. //
  6. // Note: This code uses the D3D Framework helper library.
  7. //
  8. // Copyright (c) 1998-1999 Microsoft Corporation. All rights reserved.
  9. //-----------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #define D3D_OVERLOADS
  12. #include "StdAfx.h"
  13. #include <ddraw.h>
  14. #include <d3d.h>
  15. #include "D3DApp.h"
  16. #include "D3DUtil.h"
  17. #include "D3DMath.h"
  18. #include "D3DTextr.h"
  19. #include "D3DFile.h"
  20. #include <math.h>
  21. #include <time.h>
  22. //#include <mmsystem.h>
  23. #include "dxsvr.h"
  24. #include "sealife.h"
  25. float rnd(void)
  26. {
  27. return float(rand())/RAND_MAX;
  28. }
  29. //-----------------------------------------------------------------------------
  30. // Name: CSeaLife()
  31. // Desc: Constructor
  32. //-----------------------------------------------------------------------------
  33. /*
  34. */
  35. CSeaLife::CSeaLife()
  36. {
  37. // Initialize member variables
  38. m_pDolphinGroupObject = NULL;
  39. m_pDolphinObject = NULL;
  40. m_pFloorObject = NULL;
  41. m_pFish1Object = NULL;
  42. m_pd3dDevice = NULL;
  43. m_pDeviceInfo = NULL;
  44. }
  45. //-----------------------------------------------------------------------------
  46. // Name: OneTimeSceneInit()
  47. // Desc: Called during initial app startup, this function performs all the
  48. // permanent initialization.
  49. //-----------------------------------------------------------------------------
  50. HRESULT CSeaLife::OneTimeSceneInit()
  51. {
  52. HRESULT hr;
  53. m_pDolphinGroupObject = NULL;
  54. m_pDolphinObject = NULL;
  55. m_pFloorObject = NULL;
  56. m_pFish1Object = NULL;
  57. m_pd3dDevice = NULL;
  58. m_pDeviceInfo = NULL;
  59. m_pDolphinGroupObject = new CD3DFile();
  60. m_pDolphinObject = new CD3DFile();
  61. m_pFloorObject = new CD3DFile();
  62. m_pFish1Object = new CD3DFile();
  63. hr = m_pDolphinGroupObject->Load(TEXT("dolphin_group.x"));
  64. hr |= m_pDolphinGroupObject->GetMeshVertices(TEXT("Dolph01"), &m_pDolphin1Vertices, &m_dwNumDolphinVertices);
  65. hr |= m_pDolphinGroupObject->GetMeshVertices(TEXT("Dolph02"), &m_pDolphin2Vertices, &m_dwNumDolphinVertices);
  66. hr |= m_pDolphinGroupObject->GetMeshVertices(TEXT("Dolph03"), &m_pDolphin3Vertices, &m_dwNumDolphinVertices);
  67. if (FAILED(hr))
  68. {
  69. MessageBox(NULL, TEXT("Error loading DOLPHIN_GROUP.X file"),
  70. TEXT("Dolphins"), MB_OK|MB_ICONERROR);
  71. return E_FAIL;
  72. }
  73. hr = m_pDolphinObject->Load(TEXT("dolphin.x"));
  74. hr |= m_pDolphinObject->GetMeshVertices(TEXT("Dolph02"), &m_pDolphinVertices, &m_dwNumDolphinVertices);
  75. if (FAILED(hr))
  76. {
  77. MessageBox(NULL, TEXT("Error loading DOLPHIN.X file"),
  78. TEXT("Dolphins"), MB_OK|MB_ICONERROR);
  79. return E_FAIL;
  80. }
  81. hr = m_pFloorObject->Load(TEXT("seafloor.x"));
  82. hr |= m_pFloorObject->GetMeshVertices(TEXT("SeaFloor"), &m_pFloorVertices, &m_dwNumFloorVertices);
  83. if (FAILED(hr))
  84. {
  85. MessageBox(NULL, TEXT("Error loading SEAFLOOR.X file"),
  86. TEXT("Dolphins"), MB_OK|MB_ICONERROR);
  87. return E_FAIL;
  88. }
  89. hr = m_pFish1Object->Load(TEXT("clownfish2.x"));
  90. D3DTextr_CreateTextureFromFile(TEXT("seafloor.bmp"));
  91. D3DTextr_CreateTextureFromFile(TEXT("dolphin.bmp"));
  92. srand(5);
  93. // Scale the sea floor vertices, and add some bumpiness
  94. for(DWORD i=0; i<m_dwNumFloorVertices; i++)
  95. {
  96. m_pFloorVertices[i].y += (rand()/(FLOAT)RAND_MAX);
  97. m_pFloorVertices[i].y += (rand()/(FLOAT)RAND_MAX);
  98. m_pFloorVertices[i].y += (rand()/(FLOAT)RAND_MAX);
  99. m_pFloorVertices[i].tu *= 10;
  100. m_pFloorVertices[i].tv *= 10;
  101. }
  102. // Scale the dolphin vertices (the model file is too big)
  103. for(i=0; i<m_dwNumDolphinVertices; i++)
  104. {
  105. D3DVECTOR vScale(0.01f, 0.01f, 0.01f);
  106. *((D3DVECTOR*)(&m_pDolphin1Vertices[i])) *= vScale;
  107. *((D3DVECTOR*)(&m_pDolphin2Vertices[i])) *= vScale;
  108. *((D3DVECTOR*)(&m_pDolphin3Vertices[i])) *= vScale;
  109. }
  110. for (i=0; i<NUM_FISH;i++)
  111. {
  112. ZeroMemory(&m_FishState[i],sizeof(FISHSTRUCT));
  113. m_FishState[i].type=FISHTYPE_DOLPHIN;
  114. m_FishState[i].dir=D3DVECTOR(0,0,1);
  115. m_FishState[i].goal=D3DVECTOR(XEXTENT,YEXTENT,ZEXTENT);
  116. m_FishState[i].loc=D3DVECTOR(XEXTENT,0,ZEXTENT);
  117. m_FishState[i].speed = DOLPHINSPEED;
  118. m_FishState[i].angle_tweak =TWEAK;
  119. m_FishState[i].pitch=INITPITCH;
  120. m_FishState[i].turndelta=(float)TURNDELTADOLPHIN;
  121. m_FishState[i].pitchchange= (float)PITCHCHANGE;
  122. m_FishState[i].pitchdelta= PITCHDELTA;
  123. if ((i > NUM_DOLPHINS))
  124. {
  125. m_FishState[i].type=FISHTYPE_FISH1;
  126. m_FishState[i].pitchchange= (float)PITCHCHANGEFISH;
  127. m_FishState[i].pitchdelta= PITCHDELTAFISH;
  128. m_FishState[i].turndelta=(float)TURNDELTAFISH;
  129. m_FishState[i].angle_tweak =TWEAKFISH;
  130. m_FishState[i].speed = FISHSPEED;
  131. ;
  132. }
  133. }
  134. m_FishState[0].type=FISHTYPE_CAMERA;
  135. m_FishState[0].turndelta=(float)TURNDELTADOLPHIN;
  136. m_FishState[0].angle_tweak =TWEAK;
  137. srand (time (0));
  138. return S_OK;
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Name: FinalCleanup()
  142. // Desc: Called before the app exits, this function gives the app the chance
  143. // to cleanup after itself.
  144. //-----------------------------------------------------------------------------
  145. HRESULT CSeaLife::FinalCleanup()
  146. {
  147. SAFE_DELETE(m_pDolphinGroupObject);
  148. SAFE_DELETE(m_pDolphinObject);
  149. SAFE_DELETE(m_pFloorObject);
  150. //dont cleanup device object..
  151. D3DTextr_InvalidateAllTextures();
  152. return S_OK;
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Name: BlendMeshes()
  156. // Desc: Does a linear interpolation between all vertex positions and normals
  157. // in two source meshes and outputs the result to the destination mesh.
  158. // This function assumes that all strided vertices have the same stride,
  159. // and that each mesh contains the same number of vertices
  160. //-----------------------------------------------------------------------------
  161. VOID BlendMeshes(D3DVERTEX* pDstMesh, D3DVERTEX* pSrcMesh1,
  162. D3DVERTEX* pSrcMesh2, DWORD dwNumVertices, FLOAT fWeight)
  163. {
  164. FLOAT fInvWeight = 1.0f - fWeight;
  165. // LERP positions and normals
  166. for(DWORD i=0; i<dwNumVertices; i++)
  167. {
  168. pDstMesh->x = fWeight*pSrcMesh1->x + fInvWeight*pSrcMesh2->x;
  169. pDstMesh->y = fWeight*pSrcMesh1->y + fInvWeight*pSrcMesh2->y;
  170. pDstMesh->z = fWeight*pSrcMesh1->z + fInvWeight*pSrcMesh2->z;
  171. pDstMesh->nx = fWeight*pSrcMesh1->nx + fInvWeight*pSrcMesh2->nx;
  172. pDstMesh->ny = fWeight*pSrcMesh1->ny + fInvWeight*pSrcMesh2->ny;
  173. pDstMesh->nz = fWeight*pSrcMesh1->nz + fInvWeight*pSrcMesh2->nz;
  174. pDstMesh++;
  175. pSrcMesh1++;
  176. pSrcMesh2++;
  177. }
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Name: Render()
  181. // Desc: Called once per frame, the call is the entry point for 3d
  182. // rendering. This function sets up render states, clears the
  183. // viewport, and renders the scene.
  184. //-----------------------------------------------------------------------------
  185. HRESULT CSeaLife::Render(LPDIRECT3DDEVICE7 lpDev)
  186. {
  187. float fWeight;
  188. D3DMATRIX* pmatDest=NULL;
  189. D3DUtil_SetIdentityMatrix(m_matFloor);
  190. if (lpDev!=m_pd3dDevice)
  191. {
  192. D3DTextr_RestoreAllTextures(lpDev);
  193. }
  194. m_pd3dDevice=lpDev;
  195. // Clear the viewport
  196. m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
  197. WATER_COLOR, 1.0f, 0L);
  198. // Begin the scene
  199. if (SUCCEEDED(m_pd3dDevice->BeginScene()))
  200. {
  201. m_pd3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matFloor);
  202. m_pFloorObject->Render(m_pd3dDevice);
  203. // Move the dolphin in a circle
  204. CD3DFileObject* pDolphinObject = m_pDolphinObject->FindObject(TEXT("x3ds_Dolph02"));
  205. CD3DFileObject* pFish1Object = m_pFish1Object->FindObject(TEXT("clownfish_root"));
  206. for (int i =0;i<NUM_FISH;i++)
  207. {
  208. switch (m_FishState[i].type)
  209. {
  210. case FISHTYPE_DOLPHIN:
  211. fWeight=-m_FishState[i].weight;
  212. if(fWeight < 0.0f)
  213. {
  214. BlendMeshes(m_pDolphinVertices, m_pDolphin3Vertices,
  215. m_pDolphin2Vertices, m_dwNumDolphinVertices, -fWeight);
  216. }
  217. else
  218. {
  219. BlendMeshes(m_pDolphinVertices, m_pDolphin1Vertices,
  220. m_pDolphin2Vertices, m_dwNumDolphinVertices, fWeight);
  221. }
  222. if (pDolphinObject)
  223. {
  224. m_pd3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matFloor);
  225. pmatDest = pDolphinObject->GetMatrix();
  226. *pmatDest=m_FishState[i].matrix;
  227. m_pDolphinObject->Render(m_pd3dDevice);
  228. }
  229. break;
  230. case FISHTYPE_FISH1:
  231. if (pFish1Object)
  232. {
  233. m_pd3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_matFloor);
  234. pmatDest = pFish1Object->GetMatrix();
  235. *pmatDest=m_FishState[i].matrix;
  236. m_pFish1Object->Render(m_pd3dDevice);
  237. }
  238. break;
  239. }
  240. }
  241. // End the scene.
  242. m_pd3dDevice->EndScene();
  243. }
  244. return S_OK;
  245. }
  246. //-----------------------------------------------------------------------------
  247. // Name: InitDeviceObjects()
  248. // Desc: Initialize scene objects.
  249. //-----------------------------------------------------------------------------
  250. HRESULT CSeaLife::InitDeviceObjects(LPDIRECT3DDEVICE7 pDev ,D3DEnum_DeviceInfo* pInfo)
  251. {
  252. if (!pDev) return E_FAIL;
  253. m_pd3dDevice=pDev;
  254. m_pDeviceInfo=pInfo;
  255. // Set up the lighting states
  256. // if (m_pDeviceInfo->ddDeviceDesc.dwVertexProcessingCaps &
  257. // D3DVTXPCAPS_DIRECTIONALLIGHTS)
  258. {
  259. D3DLIGHT7 light;
  260. D3DUtil_InitLight(light, D3DLIGHT_DIRECTIONAL, 0.0f, -1.0f, 0.0f);
  261. m_pd3dDevice->SetLight(0, &light);
  262. m_pd3dDevice->LightEnable(0, TRUE);
  263. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE);
  264. }
  265. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0x33333333);
  266. // Set the transform matrices
  267. D3DVIEWPORT7 vp;
  268. m_pd3dDevice->GetViewport(&vp);
  269. FLOAT fAspect = ((FLOAT)vp.dwHeight) / vp.dwWidth;
  270. D3DVECTOR vEyePt = D3DVECTOR(0.0f, 0.0f, -10.0f);
  271. D3DVECTOR vLookatPt = D3DVECTOR(0.0f, 0.0f, 0.0f);
  272. D3DVECTOR vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f);
  273. D3DMATRIX matWorld, matProj;
  274. D3DUtil_SetIdentityMatrix(matWorld);
  275. m_pd3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matWorld);
  276. D3DMATRIX matView;
  277. D3DUtil_SetViewMatrix(matView,vEyePt, vLookatPt, vUpVec);
  278. m_pd3dDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &matView);
  279. D3DUtil_SetProjectionMatrix(matProj, g_PI/3, fAspect, 1.0f, 1000.0f);
  280. m_pd3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &matProj);
  281. // Set up textures
  282. D3DTextr_RestoreAllTextures(m_pd3dDevice);
  283. m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  284. m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  285. m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  286. m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
  287. m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
  288. // Set default render states
  289. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE);
  290. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, FALSE);
  291. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE);
  292. // Turn on fog
  293. FLOAT fFogStart = 1.0f;
  294. FLOAT fFogEnd = 50.0f;
  295. FLOAT fDense = 0.5f;
  296. //note turn off fog for RGB
  297. //m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE);
  298. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE);
  299. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, WATER_COLOR);
  300. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE);
  301. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FOGDENSITY, *(DWORD*)(&fDense));
  302. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR);
  303. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FOGSTART, *((DWORD *)(&fFogStart)));
  304. m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FOGEND, *((DWORD *)(&fFogEnd)));
  305. D3DTextr_Restore(TEXT("seafloor.bmp") ,m_pd3dDevice);
  306. D3DTextr_Restore(TEXT("dolphin.bmp"), m_pd3dDevice);
  307. return S_OK;
  308. }
  309. //-----------------------------------------------------------------------------
  310. // Name: DeleteDeviceObjects()
  311. // Desc: Called when the app is exitting, or the device is being changed,
  312. // this function deletes any device dependant objects.
  313. //-----------------------------------------------------------------------------
  314. HRESULT CSeaLife::DeleteDeviceObjects()
  315. {
  316. D3DTextr_InvalidateAllTextures();
  317. return S_OK;
  318. }
  319. //-----------------------------------------------------------------------------
  320. // Name: FrameMove()
  321. // Desc: Called once per frame, the call is the entry point for animating
  322. // the scene.
  323. //-----------------------------------------------------------------------------
  324. HRESULT CSeaLife::FrameMove(FLOAT fTimeKeyIn)
  325. {
  326. D3DVECTOR vDirXZ;
  327. D3DVECTOR vDeltaXZ;
  328. float dotProd;
  329. static DWORD dwLastTime=0;
  330. float deltaspeed=.002f;
  331. DWORD dwThisTime=timeGetTime();
  332. if (dwLastTime != 0)
  333. {
  334. deltaspeed=((float)(dwThisTime-dwLastTime))/10000.0f;
  335. }
  336. dwLastTime=dwThisTime;
  337. float fT,fT2,fT3 ;
  338. D3DMATRIX matFish;
  339. D3DMATRIX matYRotate,matZRotate,matXRotate;
  340. D3DMATRIX matTrans1, matScale;
  341. D3DMATRIX matRotate1, matRotate2;
  342. D3DMATRIX matTemp,matTemp2;
  343. FLOAT fPhase;
  344. FLOAT fKickFreq;
  345. FLOAT fTimeKey;
  346. FLOAT fJiggleFreq;
  347. for (int i=0; i< NUM_FISH;i++)
  348. {
  349. //time based numbers
  350. fTimeKey=fTimeKeyIn+i*2;
  351. fKickFreq = 3*fTimeKey;
  352. fJiggleFreq = fTimeKey;
  353. fT=-(DOLPHINUPDOWN(fKickFreq));
  354. fT2=-fT/2;
  355. fT3=(float) ((3.1415/32)*sin(fTimeKeyIn/10));
  356. fPhase = (fTimeKey)/3;
  357. m_FishState[i].weight= - (float)sin(fKickFreq);
  358. //get the vector from current location to the goal
  359. vDeltaXZ=m_FishState[i].goal -m_FishState[i].loc ;
  360. vDeltaXZ.y=0;
  361. //transpose x and z coordinates to find normal to direction
  362. //only for the dolphin though
  363. vDirXZ.x =-m_FishState[i].dir.z;
  364. vDirXZ.z = m_FishState[i].dir.x;
  365. vDirXZ.y =0;
  366. //take dot product to determine what side to turn to
  367. dotProd=DotProduct(vDeltaXZ,vDirXZ);
  368. // turn by adding yaw
  369. if (dotProd < -m_FishState[i].turndelta)
  370. m_FishState[i].yaw +=m_FishState[i].angle_tweak;
  371. if (dotProd > m_FishState[i].turndelta)
  372. m_FishState[i].yaw -=m_FishState[i].angle_tweak;
  373. // now see how far we have to go up and down.
  374. float deltaY=m_FishState[i].goal.y - m_FishState[i].loc.y;
  375. if (deltaY < -m_FishState[i].pitchdelta)
  376. {
  377. m_FishState[i].pitch+=m_FishState[i].pitchchange;
  378. if (m_FishState[i].pitch > 0.8f) m_FishState[i].pitch=0.8f;
  379. }
  380. else if (deltaY > PITCHDELTA)
  381. {
  382. m_FishState[i].pitch-=m_FishState[i].pitchchange;
  383. if (m_FishState[i].pitch < -0.8f) m_FishState[i].pitch=-0.8f;
  384. }
  385. else
  386. {
  387. m_FishState[i].pitch *= .95f;
  388. }
  389. if (m_FishState[i].type==FISHTYPE_FISH1)
  390. {
  391. //note for the dolphin we will modulate the pitch
  392. D3DUtil_SetRotateYMatrix(matYRotate, (float) (m_FishState[i].yaw+FISHWIGGLE));
  393. D3DUtil_SetRotateXMatrix(matXRotate,-m_FishState[i].pitch);
  394. D3DMath_MatrixMultiply(matTemp, matXRotate, matYRotate); //ak
  395. }
  396. else if (m_FishState[i].type==FISHTYPE_CAMERA)
  397. {
  398. D3DUtil_SetRotateYMatrix(matYRotate,m_FishState[i].yaw);
  399. D3DUtil_SetRotateXMatrix(matXRotate,-m_FishState[i].pitch);
  400. D3DMath_MatrixMultiply(matTemp, matXRotate, matYRotate); //ak
  401. }
  402. else
  403. {
  404. //note for the dolphin we will modulate the pitch
  405. D3DUtil_SetRotateYMatrix(matYRotate,m_FishState[i].yaw);
  406. D3DUtil_SetRotateXMatrix(matXRotate,-m_FishState[i].pitch+fT);
  407. D3DMath_MatrixMultiply(matTemp, matXRotate, matYRotate); //ak
  408. }
  409. //extract a new direction vector
  410. m_FishState[i].dir[0] = -matTemp(2, 0);
  411. m_FishState[i].dir[1] = -matTemp(2, 1);
  412. m_FishState[i].dir[2] = -matTemp(2, 2);
  413. //normalize direction
  414. m_FishState[i].dir = Normalize(m_FishState[i].dir);
  415. if (m_FishState[i].type ==FISHTYPE_CAMERA)
  416. {
  417. D3DVECTOR local_up;
  418. D3DVECTOR from;
  419. D3DVECTOR at;
  420. D3DVECTOR loc = m_FishState[i].loc;
  421. D3DVECTOR dir = m_FishState[i].dir;
  422. D3DMATRIX view;
  423. local_up.x =matTemp(1, 0);
  424. local_up.y =matTemp(1, 1);
  425. local_up.z =matTemp(1, 2);
  426. from=loc; // - 20 * dir + 3* local_up;
  427. at= loc+dir;
  428. //SetViewParams(&from,&at,&local_up,1.0f);
  429. }
  430. //update the location
  431. //TODO make time based
  432. m_FishState[i].loc += m_FishState[i].speed *deltaspeed* m_FishState[i].dir;
  433. //if we near our goal choose another one
  434. D3DVECTOR vRes = (m_FishState[i].goal - m_FishState[i].loc);
  435. if ((((int)abs(vRes.x)) < 1) && (((int)abs(vRes.z)) < 1))
  436. {
  437. m_FishState[i].goal=D3DVECTOR(XEXTENT,YEXTENT,ZEXTENT);
  438. }
  439. if (m_FishState[i].type==FISHTYPE_FISH1)
  440. {
  441. D3DUtil_SetRotateXMatrix(matRotate2,-m_FishState[i].pitch);
  442. D3DUtil_SetScaleMatrix(matScale,10,10,10);
  443. D3DUtil_SetRotateYMatrix(matRotate1,m_FishState[i].yaw+FISHWIGGLE);
  444. if (rnd()<.01)
  445. {
  446. m_FishState[i].goal=D3DVECTOR(XEXTENT,YEXTENT,ZEXTENT);
  447. }
  448. }
  449. else if (m_FishState[i].type==FISHTYPE_CAMERA)
  450. {
  451. D3DUtil_SetRotateXMatrix(matRotate2,-m_FishState[i].pitch);
  452. D3DUtil_SetScaleMatrix(matScale,10,10,10);
  453. D3DUtil_SetRotateYMatrix(matRotate1,m_FishState[i].yaw);
  454. if (rnd()<.01)
  455. {
  456. m_FishState[i].goal=D3DVECTOR(XEXTENT,YEXTENT,ZEXTENT);
  457. }
  458. }
  459. else
  460. {
  461. D3DUtil_SetScaleMatrix(matScale,1,1,1);
  462. D3DUtil_SetRotateZMatrix(matRotate2,m_FishState[i].pitch +fT2);
  463. D3DUtil_SetRotateYMatrix(matRotate1,m_FishState[i].yaw-3.1415/2);
  464. }
  465. D3DUtil_SetTranslateMatrix(matTrans1,
  466. m_FishState[i].loc.x,
  467. m_FishState[i].loc.y,
  468. m_FishState[i].loc.z);
  469. D3DMath_MatrixMultiply(matTemp, matRotate2, matRotate1);
  470. D3DMath_MatrixMultiply(matTemp2, matTemp, matScale);
  471. D3DMath_MatrixMultiply(matFish, matTemp2, matTrans1);
  472. m_FishState[i].matrix = matFish;
  473. }
  474. return S_OK;
  475. }
  476. #if 0
  477. float dot = DotProduct (offset, FISH[i].delta);
  478. offset = CrossProduct (offset, FISH[i].delta);
  479. dot = (1.0f-dot)/2.0f * angle_tweak * 10.0f;
  480. if (offset.y > 0.01) {
  481. FISH[i].dyaw = (FISH[i].dyaw*9.0f + dot) * 0.1f;
  482. } else if (offset.y < 0.01) {
  483. FISH[i].dyaw = (FISH[i].dyaw*9.0f - dot) * 0.1f;
  484. }
  485. FISH[i].yaw += FISH[i].dyaw;
  486. FISH[i].roll = -FISH[i].dyaw * 9.0f;
  487. #endif