MeshObj.cpp
上传用户:henghua
上传日期:2007-11-14
资源大小:7655k
文件大小:14k
- #include "MeshObj.h"
- void control_plane(CMeshObj *pM, float i_time);
- void other_obj(CMeshObj *pM);
- // 功能:初始化设备,.x文件名,渲染状态(纹理、材质),运动方式,空间位置及方位,空间调整参量
- CMeshObj::CMeshObj(const LPDIRECT3DDEVICE9 dev,char *xfilename, cmeshobjconfig *config)
- {
- this->device = dev;
- this->draw_mtrls_state = config->draw_mtrls_state;
- this->draw_texs_state = config->draw_texs_state;
- this->movement_mode = config->movement_mode;
- this->translate0 = config->translate;
- this->scale0 = config->scale;
- this->rotate0 = config->rotate;
- time = timeGetTime();
- lastTime = time;
-
- // 默认空间位置及方位
- this->position = D3DXVECTOR3(0, 0, 0);
- this->vLook = D3DXVECTOR3(0, 0, 1);
- this->vUp = D3DXVECTOR3(0, 1, 0);
- this->vRight = D3DXVECTOR3(1, 0, 0);
- fRoll = 0.0; // 横滚角
- fPitch = 0.0; // 俯仰角
- fYaw = 0.0; // 偏航角
-
- // 初始化世界坐标变换矩阵
- D3DXMatrixIdentity(&matWorld0);
- D3DXMatrixScaling(&scale, config->scale.x, config->scale.y, config->scale.z);
- D3DXMatrixMultiply(&matWorld0, &matWorld0, &scale);
- D3DXMatrixTranslation(&translate, config->translate.x, config->translate.y, config->translate.z);
- D3DXMatrixMultiply(&matWorld0, &matWorld0, &translate);
- D3DXMatrixRotationX(&rotate, config->rotate.x);
- D3DXMatrixMultiply(&matWorld0, &matWorld0, &rotate);
- D3DXMatrixRotationY(&rotate, config->rotate.y);
- D3DXMatrixMultiply(&matWorld0, &matWorld0, &rotate);
- D3DXMatrixRotationZ(&rotate, config->rotate.z);
- D3DXMatrixMultiply(&matWorld0, &matWorld0, &rotate);
- position = D3DXVECTOR3(matWorld0._41, matWorld0._42, matWorld0._43);
- position /= matWorld0._44;
- D3DXMatrixIdentity(&matWorld);
- world = matWorld * matWorld0;
- strcpy(this->X_filename,xfilename);
- ZeroMemory(keys, sizeof(keys));
- load_texs_mode = 0;
- attached_par = 0;
- velosity = 0;
- }
- CMeshObj::~CMeshObj()
- {
- if( this->pMeshMtrls != NULL )
- delete []this->pMeshMtrls;
- if( this->pMeshTexs )
- {
- for( int i=0; i<this->num_mtrls; i++ )
- {
- if( this->pMeshTexs[i] )
- pMeshTexs[i]->Release();
- }
- delete []pMeshTexs;
- }
- delete []p_parSys;
- }
- HRESULT CMeshObj::Init()
- {
- // 从模型文件.x加载到网格模型对象
- if( FAILED( D3DXLoadMeshFromX( X_filename, D3DXMESH_MANAGED, this->device, &(this->pAdjacency), &(this->pMaterials), &(this->pEffectInstances),
- &(this->num_mtrls), &(this->pMesh)) ) )
- {
- MessageBox(NULL, "Could not find ***.x", "Mesh", MB_OK);
- return E_FAIL;
- }
- // 从网格模型对象中提取综合的材质纹理指针
- D3DXMATERIAL *pD3DXmtrl_tex = (D3DXMATERIAL*) this->pMaterials->GetBufferPointer();
- // 创建num_mtrls个网格材质(或后期自定义)、网格纹理、加载纹理
- if( (this->pMeshMtrls = new D3DMATERIAL9[this->num_mtrls]) == NULL )
- return E_OUTOFMEMORY;
- if( (this->pMeshTexs = new LPDIRECT3DTEXTURE9[this->num_mtrls]) == NULL )
- return E_OUTOFMEMORY;
- // 逐块提取网格模型的综合材质纹理指针中的网格材质和网格纹理
- for(int i=0; i<this->num_mtrls; i++)
- {
- // 网格材质
- this->pMeshMtrls[i] = pD3DXmtrl_tex[i].MatD3D;
- // 设置模型材料的环境光反射系数, 因为模型材料本身没有设置环境光反射系数
- if(strcmp(this->X_filename,"models\beacon_3d.x")==0)
- 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;
- this->pMeshMtrls[i].Ambient = this->pMeshMtrls[i].Diffuse;
- // 网格纹理
- this->pMeshTexs[i] = NULL;
- if( pD3DXmtrl_tex[i].pTextureFilename != NULL && strlen(pD3DXmtrl_tex[i].pTextureFilename) > 0 && this->draw_texs_state == have_texs)
- {
- // 获取纹理文件名
- CHAR fileName[256];
- //this->RemovePathFromFileName(pD3DXmtrl_tex[i].pTextureFilename, fileName);
- strcpy(fileName, pD3DXmtrl_tex[i].pTextureFilename);
- // 创建纹理
- if( FAILED( D3DXCreateTextureFromFile( device, fileName, &(this->pMeshTexs[i]) ) ) )
- {
- MessageBox(NULL, "Could not find texture file", "Mesh", MB_OK);
- }
- }
- }
- return S_OK;
- }
- void CMeshObj::Render()
- {
- device->SetRenderState(D3DRS_LIGHTING, true);
- this->SetSunLight();
- this->SetWorldMatrix();
- for(int i=0; i<this->num_mtrls; i++)
- {
- device->SetMaterial( &(this->pMeshMtrls[i]) );
- if( draw_texs_state == have_texs )
- device->SetTexture( 0, this->pMeshTexs[i] );
- if( draw_texs_state == load_texs )
- {
- if( load_texs_mode == 0 )
- device->SetTexture( 0, this->pMeshTexs[i] );
- else
- device->SetTexture( 0, this->pMeshTexs[0] );
- }
- this->pMesh->DrawSubset( i );
- }
- if(this->attached_par == 1 && this->velosity < -5)
- {
- this->p_parSys[0]->Render();
- this->p_parSys[1]->Render();
- this->p_parSys[2]->Render();
- }
- }
- void CMeshObj::RemovePathFromFileName(LPSTR fullPath, LPSTR fileName)
- {
- // 先转换类型LPSTR--〉LPWSTR
- // WCHAR wszBuf[MAX_PATH];
- // MultiByteToWideChar( CP_ACP, 0, fullPath, -1, wszBuf, MAX_PATH );
- // wszBuf[MAX_PATH-1] = L' ';
- // WCHAR *wszFullPath = wszBuf;
- LPSTR pch = strrchr(fullPath, '\');
- if(pch)
- lstrcpy(fileName, ++pch);
- else
- lstrcpy(fileName, fullPath);
- }
- void CMeshObj::SetWorldMatrix()
- {
- // 获取时间轴信息
- time = timeGetTime();
- float interval;
- interval = (time - lastTime)/1000.0f;
-
- // ***更新网格模型姿态***
- if(this->movement_mode == moving_up_freely)
- control_plane(this, interval*0.1);
- else
- {
- if(this->movement_mode == moving_on_sea)
- ControlBoat(interval*0.01);
- else
- {
- // other_obj(this);
-
- // 缩放
- /* D3DXMATRIX matScale;
- D3DXMatrixScaling(&matScale, this->scale0.x, this->scale0.y, this->scale0.z);
- D3DXMatrixMultiply(&(this->matWorld), &(this->matWorld), &matScale);
- // 位置不变
- this->matWorld._41 = this->position.x;
- this->matWorld._42 = this->position.y;
- this->matWorld._43 = this->position.z;*/
- // 设置世界坐标变换矩阵
- D3DXMATRIX world = matWorld * matWorld0;
- if(strcmp(X_filename,"models\carrier.x")==0 || strcmp(X_filename,"models\warship2.x")==0)
- {
- static float sh = 0.0f;
- sh = sh*0.9 + 0.1*seaHeight*5;
- D3DXMATRIX temp;
- D3DXMatrixTranslation(&temp, 0, sh, 0);
- world = world * temp;
- }
- device->SetTransform( D3DTS_WORLD, &world );
- position = D3DXVECTOR3(world._41, world._42, world._43);
- position /= world._44;
- }
- }
- }
- void CMeshObj::GetKey(int i) // 消息处理
- {
- keys[i] = true;
- }
- void CMeshObj::LostKey(int i) // 消息处理
- {
- keys[i] = false;
- }
- HRESULT CMeshObj::LoadTexture(char *fileName, int i)
- {
- if(i == -1)
- {
- this->load_texs_mode = 1;
- i = 0;
- gpu_tex = 0;
- }
- if( FAILED( D3DXCreateTextureFromFile( device, fileName, &(this->pMeshTexs[i]) ) ) )
- {
- MessageBox(NULL, "Could not find load texture", "lalala.exe", MB_OK);
- return E_FAIL;
- }
- return S_OK;
- }
- HRESULT CMeshObj::LoadEffect(char *fileName)
- {
- char *errortext;
- LPD3DXBUFFER errors;
- D3DXHANDLE hTechnique;
- D3DXCreateEffectFromFile(device, fileName,
- NULL, NULL, 0, NULL, &(this->pLoadEffect), &errors );
- if (errors != NULL){
- errortext = (char*) errors->GetBufferPointer();
- MessageBox(NULL, errortext, "MeshEffect.exe", MB_OK);
- return E_FAIL;
- }
- this->pLoadEffect->FindNextValidTechnique(NULL, &hTechnique);
- this->pLoadEffect->SetTechnique(hTechnique);
- return S_OK;
- }
- void CMeshObj::UpdateHeight(float height)
- {
- seaHeight = height;
- }
- void CMeshObj::SetSunLight()
- {
- // 设置太阳光
- D3DLIGHT9 sun;
- sun.Direction.x = -cos(1.00f)*sin(0.46f);
- sun.Direction.y = -sin(1.00f);
- sun.Direction.z = -cos(1.00f)*cos(0.46f);
- sun.Diffuse.r = 1.0f;
- sun.Diffuse.g = 1.0f;
- sun.Diffuse.b = 2.0f;
- sun.Diffuse.a = 1.0f;
- sun.Ambient.a = 1.0f;
- sun.Ambient.r = 0.2f;
- sun.Ambient.g = 0.3f;
- sun.Ambient.b = 0.3f;
- sun.Specular.r = 2.0f;
- sun.Specular.g = 1.0f;
- sun.Specular.b = 1.0f;
- sun.Specular.a = 1.0f;
- sun.Attenuation0 = 1.0f;
- sun.Type = D3DLIGHT_DIRECTIONAL;
- device->SetLight(0, &sun);
- device->LightEnable( 0, true);
- }
- void control_plane(CMeshObj *pM, float interval_time)
- {
- // 获取当前方位量和位置量
- pM->vLook.x = pM->matWorld._31;
- pM->vLook.y = pM->matWorld._32;
- pM->vLook.z = pM->matWorld._33;
- pM->vUp.x = pM->matWorld._21;
- pM->vUp.y = pM->matWorld._22;
- pM->vUp.z = pM->matWorld._23;
- pM->vRight.x = pM->matWorld._11;
- pM->vRight.y = pM->matWorld._12;
- pM->vRight.z = pM->matWorld._13;
- pM->position.x = pM->matWorld._41;
- pM->position.y = pM->matWorld._42;
- pM->position.z = pM->matWorld._43;
- D3DXVec3Normalize(&(pM->vLook), &(pM->vLook));
- D3DXVec3Cross(&(pM->vRight), &(pM->vUp), &(pM->vLook));
- D3DXVec3Normalize(&(pM->vRight), &(pM->vRight));
- D3DXVec3Cross( &(pM->vUp), &(pM->vLook), &(pM->vRight));
- D3DXVec3Normalize(&(pM->vUp), &(pM->vUp));
- // 更新当前的vLook,vUp,vRight
- if(pM->keys['Y'])
- pM->fPitch = 3 * interval_time;
- if(pM->keys['H'])
- pM->fPitch = -3 * interval_time;
- if(pM->keys['F'])
- pM->fYaw = -3 * interval_time;
- if(pM->keys['J'])
- pM->fYaw = 3 * interval_time;
- if(pM->keys['n'] || pM->keys['N'])
- pM->fRoll = -3 * interval_time;
- if(pM->keys['m'] || pM->keys['M'])
- pM->fRoll = +3 * interval_time;
- D3DXMatrixRotationAxis(&(pM->matYaw), &(pM->vUp), pM->fYaw);
- D3DXVec3TransformCoord(&(pM->vLook), &(pM->vLook), &(pM->matYaw));
- D3DXVec3TransformCoord(&(pM->vRight), &(pM->vRight), &(pM->matYaw));
- D3DXMatrixRotationAxis(&(pM->matRoll), &(pM->vLook), pM->fRoll);
- D3DXVec3TransformCoord(&(pM->vUp), &(pM->vUp), &(pM->matRoll));
- D3DXVec3TransformCoord(&(pM->vRight), &(pM->vRight), &(pM->matRoll));
- D3DXMatrixRotationAxis(&(pM->matPitch), &(pM->vRight), pM->fPitch);
- D3DXVec3TransformCoord(&(pM->vLook), &(pM->vLook), &(pM->matPitch));
- D3DXVec3TransformCoord(&(pM->vUp), &(pM->vUp), &(pM->matPitch));
- pM->fRoll = 0.0; // 横滚角
- pM->fPitch = 0.0; // 俯仰角
- pM->fYaw = 0.0; // 偏航角
- // 更新当前的position
- static int fly=0;
- if( pM->keys['T'] || pM->keys['t'])
- {
- if(fly!=0)
- fly += 50;
- else
- fly = 10;
-
- }
- if(fly >=9)
- {
- pM->position.x -= pM->vLook.x * fly * interval_time;
- pM->position.y -= pM->vLook.y * fly * interval_time;
- pM->position.z -= pM->vLook.z * fly * interval_time;
- if(fly <200)
- fly ++;
-
- }
- if( pM->keys['G'] || pM->keys['g'])
- {
- fly = -1*fly;
- }
- if(fly<0)
- {
- fly += 4;
- pM->position.x += pM->vLook.x * fly * interval_time;
- pM->position.y += pM->vLook.y * fly * interval_time;
- pM->position.z += pM->vLook.z * fly * interval_time;
- }
- pM->matWorld._31 = pM->vLook.x;
- pM->matWorld._32 = pM->vLook.y;
- pM->matWorld._33 = pM->vLook.z;
- pM->matWorld._21 = pM->vUp.x;
- pM->matWorld._22 = pM->vUp.y;
- pM->matWorld._23 = pM->vUp.z;
- pM->matWorld._11 = pM->vRight.x;
- pM->matWorld._12 = pM->vRight.y;
- pM->matWorld._13 = pM->vRight.z;
- pM->matWorld._41 = pM->position.x;
- pM->matWorld._42 = pM->position.y;
- pM->matWorld._43 = pM->position.z;
- }
- void CMeshObj::ControlBoat(float interval)
- {
- // 获取当前方位量和位置量
- static float tempFPitch = fPitch;
- float fPitch2;
- if(keys['D'])
- {
- fPitch = fPitch*0.99 - 0.1*0.1;
- fYaw = fYaw*0.99 + 0.1*0.05; // 根据导入模型的性质,经试验fYaw控制左右转幅度
- }
- else
- {
- fPitch = fPitch*0.99;
- fYaw = fYaw*0.9;
- }
- if(keys['A'])
- {
- fPitch = fPitch*0.99 + 0.1*0.01;
- fYaw = fYaw*0.99 - 0.1*0.05;
- }
- else
- {
- fPitch = fPitch*0.99;
- fYaw = fYaw*0.9;
- }
- fPitch2 = (fPitch - tempFPitch);
- D3DXQUATERNION qR,qR2;
- D3DXMATRIX matRot,matRot2;
- D3DXQuaternionRotationYawPitchRoll(&qR, fYaw, 0, fRoll);
- D3DXQuaternionRotationYawPitchRoll(&qR2, 0, fPitch, 0);
- D3DXMatrixRotationQuaternion(&matRot, &qR);
- D3DXMatrixRotationQuaternion(&matRot2, &qR2);
- D3DXMatrixMultiply(&matWorld, &matRot, &matWorld);
- D3DXVECTOR3 vLook;
- D3DXVECTOR3 vLook2;
- D3DXVECTOR4 vlk;
- vLook.x = matWorld._31;
- vLook.y = matWorld._32;
- vLook.z = matWorld._33;
- D3DXMATRIX rotate;
- D3DXMatrixRotationY(&rotate, -D3DX_PI/2);
- D3DXVec3Transform(&vlk, &vLook, &rotate);
- vLook2.x = vlk.x;
- vLook2.y = vlk.y;
- vLook2.z = vlk.z;
- D3DXVec3Normalize(&vLook2,&vLook2);
- if(keys['W'])
- {
- velosity = velosity * 0.3 + 0.7*0.4;
- }
- else
- {
- velosity = velosity * 0.9;
- }
- matWorld._41 += velosity*0.4*vLook2.x;
- matWorld._42 += velosity*0.4*vLook2.y;
- matWorld._43 += velosity*0.4*vLook2.z;
- D3DXVECTOR3 vUp;
- vUp.x = matWorld._21;
- vUp.y = matWorld._22;
- vUp.z = matWorld._23;
- D3DXMATRIX temp;
- static float sh = 0;
- sh = sh*0.5 + seaHeight*0.5;
- D3DXMatrixTranslation(&temp, 0, sh, 0);
- //vUp.y += seaHeight * 0.3;
- //matWorld._22 = vUp.y;
- world = matWorld * matWorld0 ;
- position.x = world._41;
- position.y = world._42;
- position.z = world._43;
- world = world * temp;
- device->SetTransform( D3DTS_WORLD, &world );
- }
- void other_obj(CMeshObj *pM)
- {
- // 获取当前方位量和位置量
- pM->vLook.x = pM->matWorld._31;
- pM->vLook.y = pM->matWorld._32;
- pM->vLook.z = pM->matWorld._33;
- pM->vUp.x = pM->matWorld._21;
- pM->vUp.y = pM->matWorld._22;
- pM->vUp.z = pM->matWorld._23;
- pM->vRight.x = pM->matWorld._11;
- pM->vRight.y = pM->matWorld._12;
- pM->vRight.z = pM->matWorld._13;
- pM->position.x = pM->matWorld._41;
- pM->position.y = pM->matWorld._42;
- pM->position.z = pM->matWorld._43;
- D3DXVec3Normalize(&(pM->vLook), &(pM->vLook));
- D3DXVec3Cross(&(pM->vRight), &(pM->vUp), &(pM->vLook));
- D3DXVec3Normalize(&(pM->vRight), &(pM->vRight));
- D3DXVec3Cross( &(pM->vUp), &(pM->vLook), &(pM->vRight));
- D3DXVec3Normalize(&(pM->vUp), &(pM->vUp));
- pM->matWorld._31 = pM->vLook.x;
- pM->matWorld._32 = pM->vLook.y;
- pM->matWorld._33 = pM->vLook.z;
- pM->matWorld._21 = pM->vUp.x;
- pM->matWorld._22 = pM->vUp.y;
- pM->matWorld._23 = pM->vUp.z;
- pM->matWorld._11 = pM->vRight.x;
- pM->matWorld._12 = pM->vRight.y;
- pM->matWorld._13 = pM->vRight.z;
- if(pM->movement_mode == fixed_on_sea)
- pM->position.y = pM->position.y * 0.3 + pM->seaHeight * 0.7 - 1;
- }
- void CMeshObj::InitParSys(cparticleconfig *config)
- {
- this->p_parSys[0] = new CParticleSystem(device, &(config[0]));
- this->p_parSys[0]->Init();
- this->p_parSys[1] = new CParticleSystem(device, &(config[1]));
- this->p_parSys[1]->Init();
- this->p_parSys[2] = new CParticleSystem(device, &(config[2]));
- this->p_parSys[2]->Init();
- this->attached_par = 1;
- }