MeshObj.cpp
上传用户:henghua
上传日期:2007-11-14
资源大小:7655k
文件大小:14k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. #include "MeshObj.h"
  2. void control_plane(CMeshObj *pM, float i_time);
  3. void other_obj(CMeshObj *pM);
  4. // 功能:初始化设备,.x文件名,渲染状态(纹理、材质),运动方式,空间位置及方位,空间调整参量
  5. CMeshObj::CMeshObj(const LPDIRECT3DDEVICE9 dev,char *xfilename, cmeshobjconfig *config)
  6. {
  7. this->device = dev;
  8. this->draw_mtrls_state = config->draw_mtrls_state;
  9. this->draw_texs_state = config->draw_texs_state;
  10. this->movement_mode = config->movement_mode;
  11. this->translate0 = config->translate;
  12. this->scale0 = config->scale;
  13. this->rotate0 = config->rotate;
  14. time = timeGetTime();
  15. lastTime = time;
  16. // 默认空间位置及方位
  17. this->position  = D3DXVECTOR3(0, 0, 0);
  18. this->vLook = D3DXVECTOR3(0, 0, 1);
  19. this->vUp = D3DXVECTOR3(0, 1, 0);
  20. this->vRight = D3DXVECTOR3(1, 0, 0);
  21. fRoll = 0.0; // 横滚角
  22. fPitch = 0.0; // 俯仰角
  23. fYaw = 0.0; // 偏航角
  24. // 初始化世界坐标变换矩阵
  25. D3DXMatrixIdentity(&matWorld0);
  26. D3DXMatrixScaling(&scale, config->scale.x, config->scale.y, config->scale.z);
  27. D3DXMatrixMultiply(&matWorld0, &matWorld0, &scale);
  28. D3DXMatrixTranslation(&translate, config->translate.x, config->translate.y, config->translate.z);
  29. D3DXMatrixMultiply(&matWorld0, &matWorld0, &translate);
  30. D3DXMatrixRotationX(&rotate, config->rotate.x);
  31. D3DXMatrixMultiply(&matWorld0, &matWorld0, &rotate);
  32. D3DXMatrixRotationY(&rotate, config->rotate.y);
  33. D3DXMatrixMultiply(&matWorld0, &matWorld0, &rotate);
  34. D3DXMatrixRotationZ(&rotate, config->rotate.z);
  35. D3DXMatrixMultiply(&matWorld0, &matWorld0, &rotate);
  36. position = D3DXVECTOR3(matWorld0._41, matWorld0._42, matWorld0._43);
  37. position /= matWorld0._44;
  38. D3DXMatrixIdentity(&matWorld);
  39. world = matWorld * matWorld0;
  40. strcpy(this->X_filename,xfilename);
  41. ZeroMemory(keys, sizeof(keys));
  42. load_texs_mode = 0;
  43. attached_par = 0;
  44. velosity = 0;
  45. }
  46. CMeshObj::~CMeshObj()
  47. {
  48. if( this->pMeshMtrls != NULL )
  49. delete []this->pMeshMtrls;
  50. if( this->pMeshTexs )
  51. {
  52. for( int i=0; i<this->num_mtrls; i++ )
  53. {
  54. if( this->pMeshTexs[i] )
  55. pMeshTexs[i]->Release();
  56. }
  57. delete []pMeshTexs;
  58. }
  59. delete []p_parSys;
  60. }
  61. HRESULT CMeshObj::Init()
  62. {
  63. // 从模型文件.x加载到网格模型对象
  64. if( FAILED( D3DXLoadMeshFromX( X_filename, D3DXMESH_MANAGED, this->device, &(this->pAdjacency), &(this->pMaterials), &(this->pEffectInstances),
  65. &(this->num_mtrls), &(this->pMesh)) ) )
  66. {
  67. MessageBox(NULL, "Could not find ***.x", "Mesh", MB_OK);
  68. return E_FAIL;
  69. }
  70. // 从网格模型对象中提取综合的材质纹理指针
  71. D3DXMATERIAL *pD3DXmtrl_tex = (D3DXMATERIAL*) this->pMaterials->GetBufferPointer();
  72. // 创建num_mtrls个网格材质(或后期自定义)、网格纹理、加载纹理
  73. if( (this->pMeshMtrls = new D3DMATERIAL9[this->num_mtrls]) == NULL )
  74. return E_OUTOFMEMORY;
  75. if( (this->pMeshTexs = new LPDIRECT3DTEXTURE9[this->num_mtrls]) == NULL )
  76. return E_OUTOFMEMORY;
  77. // 逐块提取网格模型的综合材质纹理指针中的网格材质和网格纹理
  78. for(int i=0; i<this->num_mtrls; i++)
  79. {
  80. // 网格材质
  81. this->pMeshMtrls[i] = pD3DXmtrl_tex[i].MatD3D;
  82. // 设置模型材料的环境光反射系数, 因为模型材料本身没有设置环境光反射系数
  83. if(strcmp(this->X_filename,"models\beacon_3d.x")==0)
  84. this->pMeshMtrls[i].Diffuse.a = 10.0f,this->pMeshMtrls[i].Diffuse.r = 1.0f,this->pMeshMtrls[i].Diffuse.g = 0.8f,this->pMeshMtrls[i].Diffuse.b = 0.6f;
  85. this->pMeshMtrls[i].Ambient = this->pMeshMtrls[i].Diffuse;
  86. // 网格纹理
  87. this->pMeshTexs[i] = NULL;
  88. if( pD3DXmtrl_tex[i].pTextureFilename != NULL  &&  strlen(pD3DXmtrl_tex[i].pTextureFilename) > 0 && this->draw_texs_state == have_texs)
  89. {
  90. // 获取纹理文件名
  91. CHAR fileName[256];
  92. //this->RemovePathFromFileName(pD3DXmtrl_tex[i].pTextureFilename, fileName);
  93. strcpy(fileName, pD3DXmtrl_tex[i].pTextureFilename);
  94. // 创建纹理
  95. if( FAILED( D3DXCreateTextureFromFile( device, fileName, &(this->pMeshTexs[i]) ) ) )
  96. {
  97. MessageBox(NULL, "Could not find texture file", "Mesh", MB_OK);
  98. }
  99. }
  100. }
  101. return S_OK;
  102. }
  103. void CMeshObj::Render()
  104. {
  105. device->SetRenderState(D3DRS_LIGHTING, true);
  106. this->SetSunLight();
  107. this->SetWorldMatrix();
  108. for(int i=0; i<this->num_mtrls; i++)
  109. {
  110. device->SetMaterial( &(this->pMeshMtrls[i]) );
  111. if( draw_texs_state == have_texs )
  112. device->SetTexture( 0, this->pMeshTexs[i] );
  113. if( draw_texs_state == load_texs )
  114. {
  115. if( load_texs_mode == 0 )
  116. device->SetTexture( 0, this->pMeshTexs[i] );
  117. else
  118. device->SetTexture( 0, this->pMeshTexs[0] );
  119. }
  120. this->pMesh->DrawSubset( i );
  121. }
  122. if(this->attached_par == 1 && this->velosity < -5)
  123. {
  124. this->p_parSys[0]->Render();
  125. this->p_parSys[1]->Render();
  126. this->p_parSys[2]->Render();
  127. }
  128. }
  129. void CMeshObj::RemovePathFromFileName(LPSTR fullPath, LPSTR fileName)
  130. {
  131. // 先转换类型LPSTR--〉LPWSTR
  132. // WCHAR wszBuf[MAX_PATH];
  133. // MultiByteToWideChar( CP_ACP, 0, fullPath, -1, wszBuf, MAX_PATH );
  134. // wszBuf[MAX_PATH-1] = L'';
  135. // WCHAR *wszFullPath = wszBuf;
  136. LPSTR pch = strrchr(fullPath, '\');
  137. if(pch)
  138. lstrcpy(fileName, ++pch);
  139. else
  140. lstrcpy(fileName, fullPath);
  141. }
  142. void CMeshObj::SetWorldMatrix()
  143. {
  144. // 获取时间轴信息
  145. time = timeGetTime();
  146. float interval;
  147. interval = (time - lastTime)/1000.0f;
  148. // ***更新网格模型姿态***
  149. if(this->movement_mode == moving_up_freely)
  150. control_plane(this, interval*0.1);
  151. else
  152. {
  153. if(this->movement_mode == moving_on_sea)
  154. ControlBoat(interval*0.01);
  155. else
  156. {
  157. // other_obj(this);
  158. // 缩放
  159. /* D3DXMATRIX matScale;
  160. D3DXMatrixScaling(&matScale, this->scale0.x, this->scale0.y, this->scale0.z);
  161. D3DXMatrixMultiply(&(this->matWorld), &(this->matWorld), &matScale);
  162. // 位置不变
  163. this->matWorld._41 = this->position.x;
  164. this->matWorld._42 = this->position.y;
  165. this->matWorld._43 = this->position.z;*/
  166. // 设置世界坐标变换矩阵
  167. D3DXMATRIX world =  matWorld * matWorld0;
  168. if(strcmp(X_filename,"models\carrier.x")==0 || strcmp(X_filename,"models\warship2.x")==0)
  169. {
  170. static float sh = 0.0f;
  171. sh = sh*0.9 + 0.1*seaHeight*5;
  172. D3DXMATRIX temp;
  173. D3DXMatrixTranslation(&temp, 0, sh, 0);
  174. world = world * temp;
  175. }
  176. device->SetTransform( D3DTS_WORLD, &world );
  177. position = D3DXVECTOR3(world._41, world._42, world._43);
  178. position /= world._44;
  179. }
  180. }
  181. }
  182. void CMeshObj::GetKey(int i) // 消息处理
  183. {
  184. keys[i] = true;
  185. }
  186. void CMeshObj::LostKey(int i) // 消息处理
  187. {
  188. keys[i] = false;
  189. }
  190. HRESULT CMeshObj::LoadTexture(char *fileName, int i)
  191. {
  192. if(i == -1)
  193. {
  194. this->load_texs_mode = 1;
  195. i = 0;
  196. gpu_tex = 0;
  197. }
  198. if( FAILED( D3DXCreateTextureFromFile( device, fileName, &(this->pMeshTexs[i]) ) ) )
  199. {
  200. MessageBox(NULL, "Could not find load texture", "lalala.exe", MB_OK);
  201. return E_FAIL;
  202. }
  203. return S_OK;
  204. }
  205. HRESULT CMeshObj::LoadEffect(char *fileName)
  206. {
  207. char *errortext;
  208. LPD3DXBUFFER errors;
  209. D3DXHANDLE hTechnique;
  210. D3DXCreateEffectFromFile(device, fileName, 
  211. NULL, NULL, 0, NULL, &(this->pLoadEffect), &errors );
  212. if (errors != NULL){
  213. errortext = (char*) errors->GetBufferPointer();
  214. MessageBox(NULL, errortext, "MeshEffect.exe", MB_OK);
  215. return E_FAIL;
  216. }
  217. this->pLoadEffect->FindNextValidTechnique(NULL, &hTechnique);    
  218. this->pLoadEffect->SetTechnique(hTechnique);
  219. return S_OK;
  220. }
  221. void CMeshObj::UpdateHeight(float height)
  222. {
  223. seaHeight = height;
  224. }
  225. void CMeshObj::SetSunLight()
  226. {
  227. // 设置太阳光
  228. D3DLIGHT9 sun; 
  229. sun.Direction.x = -cos(1.00f)*sin(0.46f);
  230. sun.Direction.y = -sin(1.00f);
  231. sun.Direction.z = -cos(1.00f)*cos(0.46f);
  232. sun.Diffuse.r = 1.0f;
  233. sun.Diffuse.g = 1.0f;
  234. sun.Diffuse.b = 2.0f;
  235. sun.Diffuse.a = 1.0f;
  236. sun.Ambient.a = 1.0f;
  237. sun.Ambient.r = 0.2f;
  238. sun.Ambient.g = 0.3f;
  239. sun.Ambient.b = 0.3f;
  240. sun.Specular.r = 2.0f;
  241. sun.Specular.g = 1.0f;
  242. sun.Specular.b = 1.0f;
  243. sun.Specular.a = 1.0f;
  244. sun.Attenuation0 = 1.0f;
  245. sun.Type = D3DLIGHT_DIRECTIONAL;
  246. device->SetLight(0, &sun);
  247. device->LightEnable( 0, true);
  248. }
  249. void control_plane(CMeshObj *pM, float interval_time)
  250. {
  251. // 获取当前方位量和位置量
  252. pM->vLook.x = pM->matWorld._31;
  253. pM->vLook.y = pM->matWorld._32;
  254. pM->vLook.z = pM->matWorld._33;
  255. pM->vUp.x = pM->matWorld._21;
  256. pM->vUp.y = pM->matWorld._22;
  257. pM->vUp.z = pM->matWorld._23;
  258. pM->vRight.x = pM->matWorld._11;
  259. pM->vRight.y = pM->matWorld._12;
  260. pM->vRight.z = pM->matWorld._13;
  261. pM->position.x = pM->matWorld._41;
  262. pM->position.y = pM->matWorld._42;
  263. pM->position.z = pM->matWorld._43;
  264. D3DXVec3Normalize(&(pM->vLook), &(pM->vLook));
  265. D3DXVec3Cross(&(pM->vRight), &(pM->vUp), &(pM->vLook));
  266. D3DXVec3Normalize(&(pM->vRight), &(pM->vRight));
  267. D3DXVec3Cross( &(pM->vUp), &(pM->vLook), &(pM->vRight));
  268. D3DXVec3Normalize(&(pM->vUp), &(pM->vUp));
  269. // 更新当前的vLook,vUp,vRight
  270. if(pM->keys['Y'])
  271. pM->fPitch = 3 * interval_time;
  272. if(pM->keys['H'])
  273. pM->fPitch = -3 * interval_time;
  274. if(pM->keys['F'])
  275. pM->fYaw = -3 * interval_time;
  276. if(pM->keys['J'])
  277. pM->fYaw = 3 * interval_time;
  278. if(pM->keys['n'] || pM->keys['N'])
  279. pM->fRoll = -3 * interval_time;
  280. if(pM->keys['m'] || pM->keys['M'])
  281. pM->fRoll = +3 * interval_time;
  282. D3DXMatrixRotationAxis(&(pM->matYaw), &(pM->vUp), pM->fYaw);
  283. D3DXVec3TransformCoord(&(pM->vLook), &(pM->vLook), &(pM->matYaw));
  284. D3DXVec3TransformCoord(&(pM->vRight), &(pM->vRight), &(pM->matYaw));
  285. D3DXMatrixRotationAxis(&(pM->matRoll), &(pM->vLook), pM->fRoll);
  286. D3DXVec3TransformCoord(&(pM->vUp), &(pM->vUp), &(pM->matRoll));
  287. D3DXVec3TransformCoord(&(pM->vRight), &(pM->vRight), &(pM->matRoll));
  288. D3DXMatrixRotationAxis(&(pM->matPitch), &(pM->vRight), pM->fPitch);
  289. D3DXVec3TransformCoord(&(pM->vLook), &(pM->vLook), &(pM->matPitch));
  290. D3DXVec3TransformCoord(&(pM->vUp), &(pM->vUp), &(pM->matPitch));
  291. pM->fRoll = 0.0; // 横滚角
  292. pM->fPitch = 0.0; // 俯仰角
  293. pM->fYaw = 0.0; // 偏航角
  294. // 更新当前的position
  295. static int fly=0;
  296. if( pM->keys['T'] || pM->keys['t'])
  297. {
  298. if(fly!=0)
  299. fly += 50;
  300. else
  301. fly = 10;
  302. }
  303. if(fly >=9)
  304. {
  305. pM->position.x -= pM->vLook.x * fly * interval_time;
  306. pM->position.y -= pM->vLook.y * fly * interval_time;
  307. pM->position.z -= pM->vLook.z * fly * interval_time;
  308. if(fly <200)
  309. fly ++;
  310. }
  311. if( pM->keys['G'] || pM->keys['g'])
  312. {
  313. fly = -1*fly;
  314. }
  315. if(fly<0)
  316. {
  317. fly += 4;
  318. pM->position.x += pM->vLook.x  * fly * interval_time;
  319. pM->position.y += pM->vLook.y  * fly * interval_time;
  320. pM->position.z += pM->vLook.z  * fly * interval_time;
  321. }
  322. pM->matWorld._31 = pM->vLook.x;
  323. pM->matWorld._32 = pM->vLook.y;
  324. pM->matWorld._33 = pM->vLook.z;
  325. pM->matWorld._21 = pM->vUp.x;
  326. pM->matWorld._22 = pM->vUp.y;
  327. pM->matWorld._23 = pM->vUp.z;
  328. pM->matWorld._11 = pM->vRight.x;
  329. pM->matWorld._12 = pM->vRight.y;
  330. pM->matWorld._13 = pM->vRight.z;
  331. pM->matWorld._41 = pM->position.x;
  332. pM->matWorld._42 = pM->position.y;
  333. pM->matWorld._43 = pM->position.z;
  334. }
  335. void CMeshObj::ControlBoat(float interval)
  336. {
  337. // 获取当前方位量和位置量
  338. static float tempFPitch = fPitch;
  339. float fPitch2;
  340. if(keys['D']) 
  341. {
  342. fPitch = fPitch*0.99 - 0.1*0.1; 
  343. fYaw = fYaw*0.99 + 0.1*0.05; // 根据导入模型的性质,经试验fYaw控制左右转幅度
  344. }
  345. else
  346. {
  347. fPitch = fPitch*0.99;
  348. fYaw = fYaw*0.9;
  349. }
  350. if(keys['A'])
  351. {
  352. fPitch = fPitch*0.99 + 0.1*0.01;
  353. fYaw = fYaw*0.99 - 0.1*0.05;
  354. }
  355. else
  356. {
  357. fPitch = fPitch*0.99;
  358. fYaw = fYaw*0.9;
  359. }
  360. fPitch2 = (fPitch - tempFPitch);
  361. D3DXQUATERNION qR,qR2;
  362. D3DXMATRIX matRot,matRot2;
  363. D3DXQuaternionRotationYawPitchRoll(&qR, fYaw, 0, fRoll);
  364. D3DXQuaternionRotationYawPitchRoll(&qR2, 0, fPitch, 0);
  365. D3DXMatrixRotationQuaternion(&matRot, &qR);
  366. D3DXMatrixRotationQuaternion(&matRot2, &qR2);
  367. D3DXMatrixMultiply(&matWorld, &matRot, &matWorld);
  368. D3DXVECTOR3 vLook;
  369. D3DXVECTOR3 vLook2;
  370. D3DXVECTOR4 vlk;
  371. vLook.x = matWorld._31;
  372. vLook.y = matWorld._32;
  373. vLook.z = matWorld._33;
  374. D3DXMATRIX rotate;
  375. D3DXMatrixRotationY(&rotate, -D3DX_PI/2);
  376. D3DXVec3Transform(&vlk, &vLook, &rotate);
  377. vLook2.x = vlk.x;
  378. vLook2.y = vlk.y;
  379. vLook2.z = vlk.z;
  380. D3DXVec3Normalize(&vLook2,&vLook2);
  381. if(keys['W'])
  382. {
  383. velosity = velosity * 0.3 + 0.7*0.4;
  384. }
  385. else
  386. {
  387. velosity = velosity * 0.9;
  388. }
  389. matWorld._41 += velosity*0.4*vLook2.x;
  390. matWorld._42 += velosity*0.4*vLook2.y;
  391. matWorld._43 += velosity*0.4*vLook2.z;
  392. D3DXVECTOR3 vUp;
  393. vUp.x = matWorld._21;
  394. vUp.y = matWorld._22;
  395. vUp.z = matWorld._23;
  396. D3DXMATRIX temp;
  397. static float sh = 0;
  398. sh = sh*0.5 + seaHeight*0.5;
  399. D3DXMatrixTranslation(&temp, 0, sh, 0);
  400. //vUp.y += seaHeight * 0.3;
  401. //matWorld._22 = vUp.y;
  402. world = matWorld * matWorld0 ;
  403. position.x = world._41;
  404. position.y = world._42;
  405. position.z = world._43;
  406. world = world * temp;
  407. device->SetTransform( D3DTS_WORLD, &world );
  408. }
  409. void other_obj(CMeshObj *pM)
  410. {
  411. // 获取当前方位量和位置量
  412. pM->vLook.x = pM->matWorld._31;
  413. pM->vLook.y = pM->matWorld._32;
  414. pM->vLook.z = pM->matWorld._33;
  415. pM->vUp.x = pM->matWorld._21;
  416. pM->vUp.y = pM->matWorld._22;
  417. pM->vUp.z = pM->matWorld._23;
  418. pM->vRight.x = pM->matWorld._11;
  419. pM->vRight.y = pM->matWorld._12;
  420. pM->vRight.z = pM->matWorld._13;
  421. pM->position.x = pM->matWorld._41;
  422. pM->position.y = pM->matWorld._42;
  423. pM->position.z = pM->matWorld._43;
  424. D3DXVec3Normalize(&(pM->vLook), &(pM->vLook));
  425. D3DXVec3Cross(&(pM->vRight), &(pM->vUp), &(pM->vLook));
  426. D3DXVec3Normalize(&(pM->vRight), &(pM->vRight));
  427. D3DXVec3Cross( &(pM->vUp), &(pM->vLook), &(pM->vRight));
  428. D3DXVec3Normalize(&(pM->vUp), &(pM->vUp));
  429. pM->matWorld._31 = pM->vLook.x;
  430. pM->matWorld._32 = pM->vLook.y;
  431. pM->matWorld._33 = pM->vLook.z;
  432. pM->matWorld._21 = pM->vUp.x;
  433. pM->matWorld._22 = pM->vUp.y;
  434. pM->matWorld._23 = pM->vUp.z;
  435. pM->matWorld._11 = pM->vRight.x;
  436. pM->matWorld._12 = pM->vRight.y;
  437. pM->matWorld._13 = pM->vRight.z;
  438. if(pM->movement_mode == fixed_on_sea)
  439. pM->position.y = pM->position.y * 0.3 + pM->seaHeight * 0.7 - 1;
  440. }
  441. void CMeshObj::InitParSys(cparticleconfig *config)
  442. {
  443. this->p_parSys[0] = new CParticleSystem(device, &(config[0]));
  444. this->p_parSys[0]->Init();
  445. this->p_parSys[1] = new CParticleSystem(device, &(config[1]));
  446. this->p_parSys[1]->Init();
  447. this->p_parSys[2] = new CParticleSystem(device, &(config[2]));
  448. this->p_parSys[2]->Init();
  449. this->attached_par = 1;
  450. }